Can I trust in "%" to be the SQL wildcard - sql

Hi there I'm using JPA to query a database and I should do a column like 'whatever%' query.
My DB is currently Mysql so I could do that without problem, but I was wondering if there was somewhere a method to retrieve the Wildcard character of the database.
There's little chance I change the DB but well ... I'm trying to be as generic as possible.
So is "%" the only wildcard (not talking about _) used, and will forever be ?
Thanks for info!

% is ANSI SQL. This value isn't configurable in any of the major databases, and as such there is no need for these databases to provide a method to return the wildcard character.
This should only be a concern if you think you might migrate to a non-ANSI SQL database, such as MS Access, which uses a * as a wildcard character.
If is is a possibility, I'd suggest making the wildcard character configurable in your application, and provide a variable containing the wildcard character instead of a hard-coded character.

Related

MS Access Query -LIKE x0x6

im using MS Access as DB and the Field im searching is a Short Text. would like to know how i could search a field and match it with wildcards. For example('x' is wildcard) -
x0x6 (matches 1016, 1076.....)
x06x (matches 9067, 3068....)
.
.
.
have search online and found sample using this - % ? #, but none works for me :/
here is my sql query -
SELECT COUNT(DPlace) as CounTotal
FROM tblTest2
WHERE DSide=1 AND
DNumber LIKE '%06%' AND DDate BETWEEN #09-13-16# AND #09-13-17#
SELECT COUNT(DPlace) as CounTotal
FROM tblTest2
WHERE DSide=1 AND
DNumber LIKE '%0%6' AND DDate BETWEEN #09-13-16# AND #09-13-17#
Both the sql above returns wrong result as they matches all field that has '06'. Please advice. Thank you.
Here is an explanation of why [0-9] works and ? and # does not in your LIKE pattern. TL;DR - You are using the Access backend which runs ANSI-92 mode.
Background
MS Access is a unique type of software in that it is two-fold:
FRONT-END: A GUI .exe program and part of the MS Office Suite (with Word/Excel/PowerPoint) only for Windows installs. This GUI program can serve as a "front-end" to connect to any ODBC/OLEDB compliant "back-end" RDBMS database such as SQL Server, Postgres, MySQL, SQLite, etc.
BACK-END: By default, Access GUI connects to the Windows' JET/ACE SQL Engine (Windows .dll files), a file-system data store, which over time has been considered the "Access database" but any Windows program or script can connect to it without MSAccess.exe installed. Likewise, any application layer language (VB, C#, PHP, Python, Java) with appropriate ODBC/OLEDB libraries can connect to this backend. In fact, when using the GUI, VBA is connected by default! So really Access is a GUI console to database (#1 definition).
OP as commented is using VB6 (application code) to connect to the JET/ACE engine as a backend database, no where using the GUI program.
LIKE Operator
The above dichotomy is particularly relevant concerning the LIKE operator:
Using the GUI version of Access, its SQL dialect tends to be ANSI-plus and can interface with VBA. Hence, the LIKE operator behaves very similar to VBA's LIKE operator. Also, the LIKE operator runs in ANSI-89 mode which uses the asterisk * and not % wildcard for LIKE as well as ? and #. Even so, the GUI's LIKE can use percentage symbol with the ALIKE operator or setting the database to ANSI-92 mode (and not the default ANSI-89).
Using the backend database of Access as OP does, the SQL dialect uses ANSI-92 mode which MS docs show include:
%: Matches any number of characters. It can be used as the first or last character in the character string.
_: Matches any single character within the brackets.
[]: Matches any single alphabetic character.
-: Matches any one of a range of characters. You must specify the range in ascending order (A to Z, not Z to A).
Notice unlike the ANSI-89 mode, the symbols ? and # are not included. But the last symbol, the hyphen, matches a range of characters such as digits, [0-9]. The same below SQL statement if run inside the MSAccess.exe will not return same results unless you run in ANSI-92 mode.
SELECT COUNT(DPlace) as CountTotal
FROM tblTest2
WHERE DSide=1
AND DNumber LIKE '[0-9]0[0-9]6'
AND DDate BETWEEN #09-13-16# AND #09-13-17#
MS Access uses different like patterns from other databases. These are well-documented.
From what you describe, you want either:
DNumber LIKE '?06?'
where ? can be any character.
or:
DNumber LIKE '#06#'
where # is specifically a digit.
You can also write the latter as:
DNumber LIKE '[0-9]06[0-9]'
and this will work in SQL Server as well.
In any other database, the placeholder for any character is _:
DNumber LIKE '_06_'
This does not have the same effect in MS Access.
In Access it will be:
SELECT
COUNT(*) as CounTotal
FROM
tblTest2
WHERE
DSide=1 AND DNumber LIKE '?0?6' AND DDate BETWEEN #09-13-16# AND #09-13-17#

Perl: escape sql strings without having a db connection

I know the right way to sanitize sql strings in Perl is to use a prepared statement, however, this particular Perl script is generating statements to be executed later in a different environment, not Perl. It has no database to connect to.
How can I safely escape a string for insertion into a MySQL query. The solution doesn't have to be portable.
Unfortunately the quoting function used by DBD::mysql, and the MySQL client library in general, requires an active database handle. According to the documentation, "this is needed because the escaping depends on the character set in use by the server".
I can think of a few hacky solutions, but none of them are really satisfying, so let's work with this from the docs:
Characters encoded are “\”, “'”, “"”, NUL (ASCII 0), “\n”, “\r”, and Control+Z. Strictly speaking, MySQL requires only that backslash and the quote character used to quote the string in the query be escaped.
This suggests that you can probably get away with a quoting function that does either
s/([\\"'])/\\$1/g;
or
s/([\\"'\0\n\r\cZ])/\\$1/g;
although I would still be wary.
You could just check for special chars in the variables you add to your query string that are required to do an SQL-Injection such as ";" or brackets and replace them or throw them out?!?

Is there a need to include brackets [] when running a query in SQL Server 2008?

I have SQL Server 2008 Express Edition installed and is my first time running a SQL query. I noticed that if I select to display the top 1000 rows that the query places brackets [] around the name of the database and its respective columns.
Why are there brackets around the name of the database and columns?
Is there a need to have these and if so when?
I just posted this answer on dba.stack.
They escape names that are not "friendly" - they can be useful if your database names contain special characters (such as spaces, dots or dashes) or represent SQL keywords (such as USE or DATABASE :-)). Without the square brackets, a query like this will fail:
SELECT column FROM database.dbo.table;
However if you write the query this way, the keywords are ignored:
SELECT [column] FROM [database].dbo.[table];
When building scripts or writing solutions that generate scripts from metadata (e.g. generating a script of all tables or all indexes), I always wrap entity names in square brackets so that they will work regardless of what kind of wonky names have been implemented (I am not always doing this for systems I control). You can do this easily using QUOTENAME function, e.g.:
SELECT QUOTENAME('table'), QUOTENAME('column'), QUOTENAME('database');
Results:
[table] [column] [database]
If you search my answers here for QUOTENAME you will find that I use it in a lot of scripts where I'm helping folks automate script generation or building dynamic SQL. Without the square brackets, a lot of people would run into issues running the scripts.
Enclosing a string in square braces is tells SQL Server that it should not try to parse whatever is inside them. This allows you to do use things like SQL reserved words (select, table, return, etc.) as well as spaces in identifiers. They are only required in those cases, but they are not harmful in any case.
No there isn't, but it ensures that if you had a db, table or column named as a reserved or keyword, for example date, that it wouldn't be confused with that keyword.

NHibernate: forcing square brackets in schema export?

Is there a way to tell NHibernate to use square brackets for all table and column names (like [MyColumn]) when generating the SQL schema export for MS SQL Server? I have a legacy database that uses reserved names for certain columns and running the SQL script generated using NH throws an error because of it.
I want to avoid having to specify this separately for each column.
UPDATE: I'm using the correct dialect:
MsSqlConfiguration.MsSql2008.ConnectionString(connectionString)
UPDATE 2: #UpTheCreek pointed me in the right direction - backticks, which helped me find the answer in the "NHibernate in Action" book (p. 76):
There is no way, apart from quoting all table and column names in backticks, to force NHibernate to use quoted identifiers everywhere.
Easier approach:
SchemaMetadataUpdater.QuoteTableAndColumns(config)
(Before building SessionFactory)
That will quote all the reserved names automatically.
Use backticks in your mapping files around the column names. NH should replace these with the correct character for your db dialect (in your case square brackets).
i.e. use:
<class name="SomeClass" table="`SomeTable`">
NB - It won't work with an apostrophe. The backtick is located top left on most keyboards.
You need to use (or write) the correct dialect for your database

How do I deal with quotes ' in SQL [duplicate]

This question already has answers here:
How to anticipate and escape single quote ' in oracle
(2 answers)
Closed 7 years ago.
I have a database with names in it such as John Doe etc. Unfortunately some of these names contain quotes like Keiran O'Keefe. Now when I try and search for such names as follows:
SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe'
I (understandably) get an error.
How do I prevent this error from occurring. I am using Oracle and PLSQL.
The escape character is ', so you would need to replace the quote with two quotes.
For example,
SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe'
becomes
SELECT * FROM PEOPLE WHERE SURNAME='O''Keefe'
That said, it's probably incorrect to do this yourself. Your language may have a function to escape strings for use in SQL, but an even better option is to use parameters. Usually this works as follows.
Your SQL command would be :
SELECT * FROM PEOPLE WHERE SURNAME=?
Then, when you execute it, you pass in "O'Keefe" as a parameter.
Because the SQL is parsed before the parameter value is set, there's no way for the parameter value to alter the structure of the SQL (and it's even a little faster if you want to run the same statement several times with different parameters).
I should also point out that, while your example just causes an error, you open youself up to a lot of other problems by not escaping strings appropriately. See http://en.wikipedia.org/wiki/SQL_injection for a good starting point or the following classic xkcd comic.
Oracle 10 solution is
SELECT * FROM PEOPLE WHERE SURNAME=q'{O'Keefe}'
Parameterized queries are your friend, as suggested by Matt.
Command = SELECT * FROM PEOPLE WHERE SURNAME=?
They will protect you from headaches involved with
Strings with quotes
Querying using dates
SQL Injection
Use of parameterized SQL has other benefits, it reduces CPU overhead (as well as other resources) in Oracle by reducing the amount of work Oracle requires in order to parse the statement. If you do not use parameters (we call them bind variables in Oracle) then "select * from foo where bar='cat'" and "select * from foo where bar='dog'" are treated as separate statements, where as "select * from foo where bar=:b1" is the same statement, meaning things like syntax, validity of objects that are referenced etc...do not need to be checked again. There are occasional problems that arise when using bind variables which usually manifests itself in not getting the most efficient SQL execution plan but there are workarounds for this and these problems really depend on the predicates you are using, indexing and data skew.
Input filtering is usually done on the language level rather than database layers.
php and .NET both have their respective libraries for escaping sql statements. Check your language, see waht's available.
If your data are trustable, then you can just do a string replace to add another ' infront of the ' to escape it. Usually that is enough if there isn't any risks that the input is malicious.
I suppose a good question is what language are you using?
In PHP you would do: SELECT * FROM PEOPLE WHERE SURNAME='mysql_escape_string(O'Keefe)'
But since you didn't specify the language I will suggest that you look into a escape string function mysql or otherwise in your language.
To deal quotes if you're using Zend Framework here is the code
$db = Zend_Db_Table_Abstract::getDefaultAdapter();
$db->quoteInto('your_query_here = ?','your_value_here');
for example ;
//SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' will become
SELECT * FROM PEOPLE WHERE SURNAME='\'O\'Keefe\''
Found in under 30s on Google...
Oracle SQL FAQ