9

I have a textbox where the user enters his SQL query. However,I need to make a program that validates the query before executing it in the database.

For Example:

Suppose the user enters

SELECT A1,
       A2,
       A3 
  FROM XYZ

So now, before executing the query, I need to check whether A1, A2 and A3 exists in the table XYZ or not. If not, the user should be shown an error message.

I'm not able to think of a way to proceed. So Can anyone give a basic idea with a sample code snippet about how to proceed further?

7
  • if you want just check the tablename and columns name, You can read all Object from Sys table in SQL server and cached it, and just check the object in your application.But if you want to check the syntax i have no idea. Commented Jul 27, 2016 at 6:26
  • check this question:stackoverflow.com/questions/13316328/… Commented Jul 27, 2016 at 6:26
  • 1
    You can change approach and not check a query but provide user all possible columns which user can select. Then you will be sure that all selected columns exists in database Commented Jul 27, 2016 at 6:26
  • if it's simply checking if columns exist in the database or not you can run a query again schema information tables and check if columns exist or not otherwise you might need to use some tool which can parse the query. Check these links stackoverflow.com/questions/1054984/… stackoverflow.com/questions/1525672/… Commented Jul 27, 2016 at 6:26
  • 1
    Seems like a lot of effort to go to when a SQL database will surely provide you an error anyway if the query is ill-formed or references non-existent objects. What benefit do you perceive in having your application having to duplicate (faithfully?) that work? Commented Jul 27, 2016 at 6:34

4 Answers 4

7

I doubt if you should do this:

  • what if XYZ is not a table, but a view, materialized view, stored procedure (depends on RDBMS) which returns cursor?
  • what if XYZ is a table, but user has not permission (grant) to read it?
  • what if user has no permission on, say, A2 field reading?

There're other cases which should be taken into account

  • the query can be re-written (e.g. in case of Oracle via FGA - Fine Grain Audit)
  • XYZ can be a synonym for whatever, e.g. dblink to remote table on Hadoop, while this Hadoop is temporary out of service

So I suggest executing the query without any preliminary check, but parsing and explaining exception thrown if any.

Sign up to request clarification or add additional context in comments.

2 Comments

You forgot to mention that this would be valid sql too but probably not desired: SELECT A1 FROM XYZ; DROP TABLE XYZ;. This speaks against your advice to "execute the query without any preliminary check"
@Tim Schmelter: for undesired, but still valid sql I suggest using priveleges (GRANT / REVOKE) : if DDL (and may be DML) is not desired, then we should no grant user to perform such operations. Parsing query for DROP, ALTER, may be DELETE, UPDATE etc. is, IMHO, a bad design
2

The very suitable way is excecuting the code in MS SQL and let MS SQL figure out the errors.

StringBuilder  query= new StringBuilder();

query.Append("BEGIN \n");
query.Append("BEGIN TRY \n");
query.Append("    -- Table does not exist; object name resolution   \n");
query.Append("    -- error not caught.   \n");
query.Append("    --Append the variable which holds your sql query \n");
query.Append("    --For eg.: SELECT * FROM NonexistentTable;   \n");
query.Append("    END TRY \n");
query.Append("    BEGIN CATCH \n");
query.Append("      SELECT \n");
query.Append("        ERROR_NUMBER() AS ErrorNumber \n");
query.Append("       ,ERROR_MESSAGE() AS ErrorMessage; \n");
query.Append("    END CATCH \n");
query.Append("END");

Excecute the query using ExcecuteScalar() of SQLCommand.

SQL Server will return the exact errors for the query submitted.

Comments

1

Probably you need to do it one by one. First Check whether the Table XYZ exist or not

SELECT * FROM INFORMATION_SCHEMA.TABLES 
           WHERE TABLE_NAME = 'XYZ';

Then would come to the next question that is if the field name in the table exists or not

SELECT * FROM   INFORMATION_SCHEMA.COLUMNS
          WHERE  TABLE_NAME = 'XYZ'
                 AND COLUMN_NAME = 'A1'
                 AND COLUMN_NAME = 'A2'
                 AND COLUMN_NAME = 'A3'

Comments

0

So now, before executing the query, I need to check whether A1,A2 and A3 exist in the table XYZ or not.

If you want to check if the values exists in the table you have to query in the table. Without executing the query you cannot find if the value exists in the table.

If you are working in SQL Server(for example) then you can make use of the IF EXISTS clause like

IF EXISTS(
    SELECT *
    FROM sys.columns 
    WHERE Name = 'A1' AND Name = 'A2' AND Name = 'A3' 
      AND Object_ID = Object_ID(N'XYZ'))
BEGIN

END

2 Comments

I think he can. He can query the INFORMATION_SCHEMA for column names and check that. But that needs some heavy parsing for the query to detect column names used. Unless the user have only simple queries like the one posted (With no sub-queries and aggregate functions)
@user3185569 the queries would be like the ones posted.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.