I had a problem with the accented word search and solved it in sql server by encapsulating the vowels with the symbols [], to find records with and without accents. For example, WHERE Name LIKE '% [aa] ci [oo] n%', this works well in the SQL server, but when generating the query with EF using the operator Contains this generates a very strange SQL record, and At the moment of executing the query, it seems that the server modifies the search concept by prefixing the characters "~"
I have tried use the statement Contains (concept), the Contains statement generates LIKE in sql but it modifies the string when it includes the symbols [], including in between this symbol "~"
input:
string concept = "[aá]cc[ií][oó]n" //-> that works in sql server query
EF Query:
using (Entities ctx = new Entities())
{
ctx.Database.Log = Console.Write;
var result = ctx.Product.Where(w =w.Name.Contains(concept)).ToList();
return result;
}
The sql generated:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent1].[Description] AS [Description],
[Extent1].[Price] AS [Price]
FROM [dbo].[Product] AS [Extent1]
WHERE [Extent1].[Name] LIKE #p__linq__0 ESCAPE '~'
-- p__linq__0: '%~[aá]cc~[ií]~[oó]n%' (Type = AnsiString, Size = 8000)
the "~[aá]cc~[ií]~[oó]n" is different to the "[aá]cc[ií][oó]n" from EF
in EF the input is string, and when sql is executed the input is AnsiString and set stranger characters
SQL Server uses the square brackets as part of their wildcard expression searching, so if you want to search on them as a string they need to be escaped. While using .Contains() will result in a LIKE query, EF is treating the expression as a literal for "%value%" so it will escape any brackets or wildcard characters.
EF is escaping them with the Tilde, so it registers Tilde as the escape character in the generated script.
https://www.techonthenet.com/sql_server/like.php
Since you want to use the [] for the wildcard like operation, you need to use DbFunctions.Like with your bracketed expression.
var result = ctx.Product.Where(w=> DbFunctions.Like(w.Name, concept)).ToList();
Related
I inserted a bunch of rows with a text field like content='...\n...\n...'.
I didn't use e in front, like conent=e'...\n...\n..., so now \n is not actually displayed as a newline - it's printed as text.
How do I fix this, i.e. how to change every row's content field from '...' to e'...'?
The syntax variant E'string' makes Postgres interpret the given string as Posix escape string. \n encoding a newline is only one of many interpreted escape sequences (even if the most common one). See:
Insert text with single quotes in PostgreSQL
To "re-evaluate" your Posix escape string, you could use a simple function with dynamic SQL like this:
CREATE OR REPLACE FUNCTION f_eval_posix_escapes(INOUT _string text)
LANGUAGE plpgsql AS
$func$
BEGIN
EXECUTE 'SELECT E''' || _string || '''' INTO _string;
END
$func$;
WARNING 1: This is inherently unsafe! We have to evaluate input strings dynamically without quoting and escaping, which allows SQL injection. Only use this in a safe environment.
WARNING 2: Don't apply repeatedly. Or it will misinterpret your actual string with genuine \ characters, etc.
WARNING 3: This simple function is imperfect as it cannot cope with nested single quotes properly. If you have some of those, consider instead:
Unescape a string with escaped newlines and carriage returns
Apply:
UPDATE tbl
SET content = f_eval_posix_escapes(content)
WHERE content IS DISTINCT FROM f_eval_posix_escapes(content);
db<>fiddle here
Note the added WHERE clause to skip updates that would not change anything. See:
How do I (or can I) SELECT DISTINCT on multiple columns?
Use REPLACE in an update query. Something like this: (I'm on mobile so please ignore any typo or syntax erro)
UPDATE table
SET
column = REPLACE(column, '\n', e'\n')
I need to find all the instances of the string: "TEXT\00" (nvarchar type field)
select * from table
where contains(TEXT_Extracted, '"TEXT\00"')
However, this returns the instances of TEXT fallowed by space ("TEXT ").
I am using T-SQL 2008.
select * from table
where contains(TEXT_Extracted, '"TEXT$\00"') ESCAPE '$'
I need to update a record, which contains literal percent signs, using PostgreSQL in Railo. The query looks like
<cfquery>
update foo set bar = 'string with % in it %'
</cfQuery>
It throws error as ColdFusion normally interprets it as a wildcard character. I can escape it using the following query.
<cfquery>
update foo set bar = 'string with escaped \% in it \%'
</cfQuery>
However, the record now contains "\%" in the database and will be displayed on the page as "\%".
I found a documentation with an example of escaping percent sign in a SELECT. But it does not work for me: syntax error at or near "ESCAPE".
SELECT emp_discount
FROM Benefits
WHERE emp_discount LIKE '10\%'
ESCAPE '\';
Is there a better to achieve the same goal? The underlining database is PostgreSQL. Thanks!
Queryparameters escape special characters. Yet another reason to use them.
In JPQL what is escape character we can use to escape characters such as "'"?
Ex : I am doing something like
...where person.name='Andy'
Here it is working fine
but when the person's name is Andy's then the where clause becomes like
...where person.name='Andy's'
and it returns an error saying
It cannot figure out where string literal ends. Solution is nicely told in specification:
A string literal that includes a single quote is represented by two
single quotes—for example: ‘literal’’s’.
In your case means:
...where person.name='Andy''s'
Below is the sample code for executing query using named parameter.
Query query = entityManager.createQuery("SELECT p FROM Person p WHERE p.name LIKE :name" );
query.setParameter("name", personName);
Here, you can pass string to personName which may contain special character like "Andy's".
Also, it looks much clean & doesn't require to check parameter before query execution & altering the search string.
I have basic stored procedure that performs a full text search against 3 columns in a table by passing in a #Keyword parameter. It works fine with one word but falls over when I try pass in more than one word. I'm not sure why. The error says:
Syntax error near 'search item' in the full-text search condition 'this is a search item'
SELECT S.[SeriesID],
S.[Name] as 'SeriesName',
P.[PackageID],
P.[Name]
FROM [Series] S
INNER JOIN [PackageSeries] PS ON S.[SeriesID] = PS.[PackageID]
INNER JOIN [Package] P ON PS.[PackageID] = P.[PackageID]
WHERE CONTAINS ((S.[Name],S.[Description], S.[Keywords]),#Keywords)
AND (S.[IsActive] = 1) AND (P.[IsActive] = 1)
ORDER BY [Name] ASC
You will have to do some pre-processing on your #Keyword parameter before passing it into the SQL statement. SQL expects that keyword searches will be separated by boolean logic or surrounded in quotes. So, if you are searching for the phrase, it will have to be in quotes:
SET #Keyword = '"this is a search item"'
If you want to search for all the words then you'll need something like
SET #Keyword = '"this" AND "is" AND "a" AND "search" AND "item"'
For more information, see the T-SQL CONTAINS syntax, looking in particular at the Examples section.
As an additional note, be sure to replace the double-quote character (with a space) so you don't mess up your full-text query. See this question for details on how to do that: SQL Server Full Text Search Escape Characters?
Further to Aaron's answer, provided you are using SQL Server 2016 or greater (130), you could use the in-built string fuctions to pre-process your input string. E.g.
SELECT
#QueryString = ISNULL(STRING_AGG('"' + value + '*"', ' AND '), '""')
FROM
STRING_SPLIT(#Keywords, ' ');
Which will produce a query string you can pass to CONTAINS or FREETEXT that looks like this:
'"this*" AND "is*" AND "a*" AND "search*" AND "item*"'
or, when #Keywords is null:
""