Regular Expression in SQL statement - sql

I'm new in regular expression, and would like to ask help with the problem I have. I had a form, and it has drop down field where user can select one or more values, so the value for that drop down can be Faculty of Arts (if user chose one option) or Faculty of Arts, Faculty of Medicine (if user chose these two from the drop down).
Now, I want to convert this value, so that I can use it to filter my query. I will use this / these value(s) in WHERE clause. In this case, I have to reformat this value to "Faculty of Arts", "Faculty of Medicine", so it will fit in this statement:
SELECT * FROM myTable WHERE t_faculty IN ("Faculty of Arts", "Faculty of Medicine")
A friend of mine suggested me to try regular expression embedded in this SQL statement (I'm using SQL Server for the database). Do you have any idea on how to parse, and embed it in the SQL statement? Basically I need to add " characters in the beginning and end of the string, and replace the ,[space] with ",[space]" to get the wanted result.
Thank you!
Agus

You can split a comma-delimited string within SQL using STRING_SPLIT.
select * from myTable
where t_faculty in (
select value from string_split('Faculty of Arts, Faculty of Medicine', ',')
)
STRING_SPLIT returns a table of string values that are separated by the delimiter in the input string.
Otherwise you can use several pattern matching functions:
LIKE
PATINDEX
An SQL CLR (e.g.: C#) function that does expression matching. See SQL Server Regex.
You may also choose to simply split the string in your app. Then build the appropriate SQL command (or use something like Contains in linq).

You are not clear how you are passing those strings to SQL Server.
And SQL Server delimits strings with single quotes, i.e apostrophes not double quotes.
In whatever client-side code you have access to, simply concatenate the selected strings with apostrophes.
So if a user picks Faculty of Arts and Faculty of Medicine then you can join it all into one long string like
"'" & <selected option> & "'" & ",'" & <selected option> & "'"

You don't use regular expressions here to change the highlighted part of your SQL code :
SELECT FROM myTable WHERE t_faculty IN **("Faculty of Arts", "Faculty of Medicine")
I think your understanding about the way we use Regular Expressions could be wrong. You generally use regular expressions when you are trying to match with strings in your database which share some common properties. For instance if you have two rows with the fields "Faculty of Arts 1" and "Faculty of Arts 2". And you are trying to look up all the rows which have "Faculty of Arts" in general, then you could write it as SELECT * FROM myTABLE WHERE t_faculty LIKE 'Faculty of Arts*' where * would match anything after the text.
Instead of t_faculty IN (value1,value2), you will write something like t_faculty LIKE 'your regular_expression here'.

Related

Using Regex to determine what kind of SQL statement a row is from a list?

I have a large list of SQL commands such as
SELECT * FROM TEST_TABLE
INSERT .....
UPDATE .....
SELECT * FROM ....
etc. My goal is to parse this list into a set of results so that I can easily determine a good count of how many of these statements are SELECT statements, how many are UPDATES, etc.
so I would be looking at a result set such as
SELECT 2
INSERT 1
UPDATE 1
...
I figured I could do this with Regex, but I'm a bit lost other than simply looking at everything string and comparing against 'SELECT' as a prefix, but this can run into multiple issues. Is there any other way to format this using REGEX?
You can add the SQL statements to a table and run them through a SQL query. If the SQL text is in a column called SQL_TEXT, you can get the SQL command type using this:
upper(regexp_substr(trim(regexp_replace(SQL_TEXT, '\\s', ' ')),
'^([\\w\\-]+)')) as COMMAND_TYPE
You'll need to do some clean up to create a column that indicates the type of statement you have. The rest is just basic aggregation
with cte as
(select *, trim(lower(split_part(regexp_replace(col, '\\s', ' '),' ',1))) as statement
from t)
select statement, count(*) as freq
from cte
group by statement;
SQL is a language and needs a parser to turn it from text into a structure. Regular expressions can only do part of the work (such as lexing).
Regular Expression Vs. String Parsing
You will have to limit your ambition if you want to restrict yourself to using regular expressions.
Still you can get some distance if you so want. A quick search found this random example of tokenizing MySQL SQL statements using regex https://swanhart.livejournal.com/130191.html

Regex validation of table schema and name

I have an API that performs some query on a table that the caller specifies. The table name is placed in the query via string replace, and so is a risk for SQL injection.
Example:
tableName = req.body.tableName;
sql = "SELECT * FROM <<TABLE_NAME>>;";
sql = sql.replace("<<TABLE_NAME>>", tableName);
I'm required to keep this query dynamic, as we don't want to redeploy this code every time we add a new table. In other words, I can't just maintain a list of valid table names.
So for the purposes of keeping this safe from sql injection, is it sufficient to do a regex validation on the table name? We can be certain the table name will always be of the format schema.table_name where table_name will be only a-z, 0-9, -, _
Is there any sql injection that could slip past this table name regex?
^myschema\.[a-zA-Z0-9-_]+$
Since minus is not a valid character in a tablename, you could change your regex to just:
^myschema\.\w+$
\w is equivalent to [a-zA-Z0-9_]
There is no risk of injection.
Most databases allow special characters, even spaces and minuses, in table names if special syntax is used, eg
MySQL: `my stupid table-name!`
Postgres: "my stupid table-name!"
SQL Server: [my stupid table-name!]
It is poor practice to allow non-standard characters in names in the first place, and it would be fine to deny such names in your situation.
The minus sign cannot be used as an identifier in SQL. In the case of table names, I don't think it will lead to SQL injection attacks, but if you allow minus signs in column names, subtraction can be injected.
In the case of MySQL, the following SQL statement will return all users, not just 'tom'. This is because of the implicit type conversion that occurs when subtracting from a string.
SELECT * FROM users WHERE myschema.user-0 = 'tom'
The workaround is to exclude the minus sign or quote the identifier. The following will not result in a SQL injection attack.
SELECT * FROM users WHERE `myschema`.`user-0` = 'tom'.
The above is the way to write for MySQL, and the way to write for standard SQL is as follows
SELECT * FROM users WHERE "myschema"."user-0" = 'tom'

Asp Classic & Firbird Sql without quotation marks

I have a script in ASP Classic that uses a Firebird database. I would like to execute a query without "quotation marks"
Now I must write this:
SQL = "SELECT ""TArticoli"".""IDArticolo"",""TArticoli"".""Desc"" FROM ""TArticoli"";"
I would write this:
SQL = "SELECT TArticles.IDArticle, TArticles.Desc FROM TArticles;"
The first one is accepted the second not, how can I do this?
You can't. DESC is a reserved word in Firebird, so to be able to use it as a column name (or any other object name for that matter), you will need to enclose it in quotes.
A second problem is that you are currently using
SELECT "TArticoli"."IDArticolo","TArticoli"."Desc" FROM "TArticoli"
And this means both your table name and the column names are case sensitive, and in that case, quoting those object names is mandatory. Unquoted object names are case insensitive, but are mapped to object names in upper case. This means that select * from TArticoli will select from a table called TARTICOLI, while select * from "TArticoli", selects from a table called TArticoli.
So unless you are going to rename or recreate all your tables or columns, you will not be able to get rid of quotes. The only thing you can do to reduce the number of quotes, is by not prefixing the columns with the table names (in the query shown it isn't necessary), or otherwise use a case insensitive alias for the table, eg
SELECT "IDArticolo", "Desc" FROM "TArticoli"
or
SELECT a."IDArticolo", a."Desc" FROM "TArticoli" AS a

Finding the "&" character in SQL SERVER using a like statement and Wildcards

I need to find the '&' in a string.
SELECT * FROM TABLE WHERE FIELD LIKE ..&...
Things we have tried :
SELECT * FROM TABLE WHERE FIELD LIKE '&&&'
SELECT * FROM TABLE WHERE FIELD LIKE '&\&&'
SELECT * FROM TABLE WHERE FIELD LIKE '&|&&' escape '|'
SELECT * FROM TABLE WHERE FIELD LIKE '&[&]&'
None of these give any results in SQLServer.
Well some give all rows, some give none.
Similar questions that didn't work or were not specific enough.
Find the % character in a LIKE query
How to detect if a string contains special characters?
some old reference Server 2000
http://web.archive.org/web/20150519072547/http://sqlserver2000.databases.aspfaq.com:80/how-do-i-search-for-special-characters-e-g-in-sql-server.html
& isn't a wildcard in SQL, therefore no escaping is needed.
Use % around the value your looking for.
SELECT * FROM TABLE WHERE FIELD LIKE '%&%'
Your statement contains no wildcards, thus is equivalent to WHERE FIELD = '&'.
& isn't a special character in SQL so it doesn't need to be escaped. Just write
WHERE FIELD LIKE '%&%'
to search for entries that contain & somewhere in the field
Be aware though, that this will result in a full table scan as the server can't use any indexes. Had you typed WHERE FIELD LIKE '&%' the server could do a range seek to find all entries starting with &.
If you have a lot of data and can't add any more constraints, you should consider using SQL Server's full-text search to create and use and FTS index, with predicates like CONTAINS or FREETEXT

how to retrieve sql column includes special characters and alphabets

How to retrieve a column containing special characters including alphabets in SQL Query. i have a column like this 'abc%def'. i want to retrieve '%' based columns from that table.
Please help me in this regard.
Is abc%def the column name? or column value? Not sure what you are asking but if you mean your column name contains special character then you can escape them which would be different based on specific RDBMS you are using
SQL Server use []
select [abc%def] from tab
MySQL use backquote
select `abc%def` from tab
EDIT:
Try like below to fetch column value containing % character (Checked, it works in Ingres as well)
select * from tab where col like '%%%'
Others suggest that like '%%%' works in Ingres. So this is something special in Ingres. It does not work in other dbms.
In standard SQL you would have to declare an escape character. I think this should work in Ingres, too.
select * from mytable where str like '%!%%' escape '!';