I need to replace single quotes in a string of numbers and use in a WHERE IN clause. for example, I have
WHERE Group_ID IN (''4532','3422','1289'')
The criteria within parenthesis is being passed as a parameter, so I have no control over that. I tried using :
WHERE Group_ID IN (REGEXP_REPLACE(''4532','3422','1289'', '[']', ' ',1,0,i))
also tried using OReplace
WHERE Group_ID IN (OReplace(''4532','3422','1289'', '[']', ' '))
but get the same error:
[Teradata Database] [3707] Syntax error, expected something like ','
between a string or a Unicode character literal and the integer '4532'.
Please suggest how to remove the single enclosing quotes or even removing all single quotes should work as well.
The string ''4532','3422','1289'' you are using is incorrect because it contains non-escaped single quotes. This is a syntax error in SQL. In this particular form, no matter what function you use to fix it or which RDBMS you use, it will result in error with standard SQL.
Functions in the SQL cannot fix syntax errors. REGEXP_REPLACE and OReplace never get executed because the query never enters the execution state. It never goes past the SQL syntax parser.
To see the error from perspective of the SQL parser, you may break the string in to multiple parts
'' -- SQL Parser sees this as a starting and ending quote and hence an empty string
4532 -- Now comes what appears to SQL parser as an integer value
',' -- Now this is a pair of quotes containing a single comma
3422 -- Again an integer
',' -- Again a comma
1289 -- Again integer
'' -- Again emtpy string
This amalgam of strings and numbers will not mean anything to the SQL parser and will result in an error.
Fix
The fix is to properly escape the data. Single quotes must be escaped using another preceding single quote. So correct string in this scenario becomes '''4532'',''3422'',''1289'''
Another thing is that the OReplace usage (once syntax is fixed) is like OReplace(yourStringValueHere, '''', ' ')) Observe the usage of escaped single quote here. Two outer quotes are for the string start and end. First inner quote is the escape character and second inner quote is the actual data passed to the function.
Related
yaml = ruamel.yaml.YAML()
yaml.indent(mapping=4)
test_yaml_file = open("test.yaml")
test_file = yaml.load(test_yaml_file)
# test = LiteralScalarString('*clvm')
test = "*testing"
test_file['test_perf'] = test
with open("test.yaml", 'w') as changed_file:
yaml.dump(test_file, changed_file)
In this the expected output was
test_perf: *testing
but the output has been
test_perf: '*testing'
how to achieve this using ruamel?
Your scalar starts with a *, which is used in YAML to indicate an alias node. To prevent *testing to be interpreted as an alias during loading (even though the corresponding anchor (&testing) is not specified in the document), the scalar must be quoted or represented as a literal or folded block scalar.
So there is no way to prevent the quotes from happening apart from choosing to represent the scalar as literal or folded block scalar (where you don't get the quotes, but do get the | resp. >)
You should not worry about these quotes, because after loading you'll again have the string *testing and not something that all of a sudden has extra (unwanted) quotes).
There are other characters that have special meaning in YAML (&, !, etc.) and when indicated at the beginning of a scalar cause the scalar to be quoted. What the dump routine actually does is dump the string and read it back and if that results in a different value, the dumper knows that quoting is needed. This also works with strings like 2022-01-28, which when read back result in a date, such strings get quoted automatically when dumped as well (same for strings that look like floats, integers, true/false values).
I'm trying to insert some information to MySQL with Pascal, but when I run the program I get the error
unknown column 'mohsen' in field list
This is my code
procedure TForm1.Button1Click(Sender: TObject);
var
aSQLText: string;
aSQLCommand: string;
namee:string;
family:string;
begin
namee:='mohsen';
family:='dolatshah';
aSQLText:= 'INSERT INTO b_tbl(Name,Family) VALUES (%s,%s)';
aSQLCommand := Format(aSQLText, [namee, family]);
SQLConnector1.ExecuteDirect(aSQLCommand);
SQLTransaction1.Commit;
end;
How can I solve this problem?
It's because your
VALUES (%s,%s)
isn't surrounding the namee and family variable contents by quotes. Therefore, your back-end Sql engine thinks your mohsen is a column name, not a value.
Instead, use, e.g.
VALUES (''%s'',''%s'')
as in
Namee := 'mohsen';
Family := 'dolatshah';
aSQLText:= 'INSERT INTO b_tbl(Name,Family) VALUES (''%s'',''%s'')';
aSQLCommand := Format(aSQLText,[namee,family]);
In the original version of my answer, I explained how to fix your problem by "doubling up" single quotes in the Sql you were trying to build, because it seemed to me that you were having difficulty seeing (literally) what was wrong with what you were doing.
An alternative (and better) way to avoid your problem (and the one I always use in real life) is to use the QuotedStr() function. The same code would then become
aSQLText := 'INSERT INTO b_tbl (Name, Family) VALUES (%s, %s)';
aSQLCommand := Format(aSQLText, [QuotedStr(namee), QuotedStr(family)]);
According to the Online Help:
Use QuotedStr to convert the string S to a quoted string. A single quote character (') >is inserted at the beginning and end of S, and each single quote character in the string is >repeated.
What it means by "repeated" is what I've referred to as "doubling up". Why that's important, and the main reason I use QuotedStr is to avoid the Sql db-engine throwing an error when the value you want to send contains a single quote character as in O'Reilly.
Try adding a row containing that name to your table using MySql Workbench and you'll see what I mean.
So, not only does using QuotedStr make constructing SQL statements as strings in Delphi code less error-prone, but it also avoid problems at the back-end, too.
Just in case this will help anybody else I had the same error when I was parsing a python variable with a sql statement and it had an if statement in i.e.
sql="select bob,steve, if(steve>50,'y','n') from table;"
try as I might it coming up with this "unknown column y" - so I tried everything and then I was about to get rid of it and give it up as a bad job until I thought I would swap the " for ' and ' for "..... Hoooraaahh it works!
This is the statement that worked
sql='select bob,steve, if(steve>50,"y","n") from table;'
Hope it helps...
To avoid this sort of problem and SQL injection you should really look into using SQL parameters for this, not the Pascal format statement.
I am currently trying to create a dynamic Select statement when the user has to input a various amount of criteria to search by.
Currently, I have every part of the statement working except for the most important part.
I am attempting to do something like this:
selStmt := 'SELECT column_one, column_2, column_3
FROM nerf
whereClause := ' WHERE TO_NUMBER('''|| column_one ||''') <= '''|| userInput ||'''';
However, in doing this the WHERE cluse of my SELECT statement is not accurate as shown by my output line:
WHERE TO_NUMBER('') <= '5';
I have tried various solutions with quote marks and I end up with either a ORA-00905 missing identifier error, or I get a ORA-00911: invalid character error.
At this point I'm not quite sure how to approach this issue.
Any useful help gets thanks in advance.
For some reason, Oracle uses the single quote to delimit strings and to escape characters, so using '' is an instruction to Oracle to add a quote inside your string. Example:
'This is a string with a quote here: '' and then it ends normally'
will be represented as
This is a string with a quote here: ' and then it ends normally
In your example, you are ending the WHERE clause you're building up and then concatenating a PL/SQL variable identifier called column_one:
' WHERE TO_NUMBER('''|| column_one ||''')
...and with a NULL value for the identifier column_one this is represented as
WHERE TO_NUMBER('')
Presumably you want to reference column_one from inside the query, and not from a PL/SQL variable of the same name, so you should remove the quotes around it like so:
whereClause := ' WHERE TO_NUMBER(column_one) <= TO_NUMBER('''|| userInput ||''')';
Escaping strings in Oracle is often infuriating - it helps a lot if you have a good IDE with decent syntax highlighting like TOAD or SQL*Developer.
This should work:
selStmt := 'SELECT column_one, column_2, column_3 FROM nerf';
whereClause := ' WHERE TO_NUMBER(column_one) <= TO_NUMBER('''|| userInput ||''')';
Excerpt from SQLite reference on sqlite3_mprintf() API
http://www.sqlite.org/c3ref/mprintf.html
"The %Q option works like %q except it also adds single quotes around the outside of the total string. Additionally, if the parameter in the argument list is a NULL pointer, %Q substitutes the text "NULL" (without single quotes)."
When using %q, we have to be careful to always use single quotes around it e.g.
char *zText = "It's a happy day!";
char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
It seems more convenient to always use %Q instead of %q as follows:
char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
My question - is there a valid use case where '%q' is more suitable or more efficient? Or can I safely use %Q as a replacement for %s in all statements?
Everything is about to create SQL-statements in a secure way to minimize the possibility of SQL-injections.
You should prefer %q over %s all the time.
The %q option works like %s in that it substitutes a nul-terminated string from the argument list. But %q also doubles every '\'' character. %q is designed for use inside a string literal. By doubling each '\'' character it escapes that character and allows it to be inserted into the string.
The %Q has some futher advantages over %q.
The %Q option works like %q except it also adds single quotes around the outside of the total string. Additionally, if the parameter in the argument list is a NULL pointer, %Q substitutes the text "NULL" (without single quotes).
This means it will add single quotes and it will render nul pointers as the string literal "NULL" inside the string.
As you can see it depends on what you want to do. If you are ok with adding single quotes and that "NULL" generating behavior you can simply use %Q (I think it makes highly sense for paramter values in SQL-statements). Maybe sometimes you dont want this behavior then you can fall back to %q.
Have a simple query it's failing for one set of parameters but it works for other parameters it's not working.
This works:
SELECT R.*
FROM ROUTEUSER.AHC_B2B_ROUTE R
WHERE R.PRODUCER = 'Encounters'
AND REGEXP_LIKE ('tplmcoce.41.20170822.txt', R.FILEMASK, 'i')
This is not working
SELECT R.*
FROM ROUTEUSER.AHC_B2B_ROUTE R
WHERE R.PRODUCER = 'Facets'
AND REGEXP_LIKE ('SMS-0162628062', R.FILEMASK, 'i')
If I have a column called Filemask (REGEX Pattern) in database so how can I select matching pattern for given string (file name)?
When I try the second query I am getting the following exception:
ORA-12725: unmatched parentheses in regular expression 12725. 00000 - "unmatched
parentheses in regular expression"
*Cause: The regular expression did not have balanced parentheses.
*Action: Ensure the parentheses are correctly balanced.
SELECT R.*
FROM ROUTEUSER.AHC_B2B_ROUTE R
WHERE R.PRODUCER = 'Facets'
AND REGEXP_LIKE ('^SMS[-]0162628062$*', R.FILEMASK, 'i') ---- Try and let us know output......................
Here is a thought...
select *
from <your_table>
where regexp_count( FILEMASK, '\(' ) != regexp_count( FILEMASK, '\)' )
;
You should find at least one where PRODUCER = 'Facets' (and perhaps more?)
... although this may not be enough. Consider this regexp: '\(abc)' (where you meant '\(abc\)'). You want literal parentheses around the string abc. But you only escaped the opening parenthesis and forgot to escape the closing one. For a regular expression, that is an error: the escaped parenthesis is treated as any other character, it is not "special" in any way; this leaves the closing parenthesis as a special character, and it is not matched by an opening one.
On the other hand, my solution above is not able to distinguish between escaped and non-escaped parentheses - it treats them all the same, so '\(abc)' looks perfectly fine to it. If what I posted above is not enough, you/we will need more subtle ideas. Perhaps:
...
where regexp_count( FILEMASK, '([^\]|^)\(' ) != regexp_count( FILEMASK, '([^\]|^)\)'
This only looks for non-escaped parentheses. [^\] means "any character other than a backslash", and ([^\]|^) means either that or the beginning of the string.
This issue is resolved. This is because I had one bad regular expression (missed one parenthesis) which caused the failure. The REGEX_LIKE started comparing each mask in table column when it come to the bad regex it failed.
Please close this question.
Thanks all.
Escape the Chars in the [] with '\' . And you have to replace the last char '.' with * in the second pattern('SMS...')
^tplmcoce[\.](37|41|47|57)[\.].*[\.]txt$
and
^SMS[\-]0162628062$*
SELECT 1 Matched
FROM DUAL
WHERE REGEXP_LIKE ('tplmcoce.41.20170822.txt',
'^tplmcoce[\.](37|41|47|57)[\.].*[\.]txt$', 'i');
SELECT 1 Matched
FROM DUAL
WHERE REGEXP_LIKE ('SMS-0162628062', '^SMS[\-]0162628062$*', 'i')