check select statement is valid or not in c#.net - sql-server-2000

i want to check select statement(string) is valid or not in c#.net, if select statement is right then retrieve data and fill dropdown list box else drop down should be empty

How often would the select statement be invalid? Seems like a simple try/catch block around the execution of the SQL might be sufficient.
As an aside, I hope you aren't making an app that would allow someone to type in arbitrary SQL into a box which you would then execute...

One approach which covers most scenarios is to execute the SQL with SET FMTONLY ON
e.g.
SET FMTONLY ON;
SELECT SomeField FROM ExampleQuery
From BOL, SET FMTONLY :
Returns only metadata to the client.
Can be used to test the format of the
response without actually running the
query.query.
That will error if the query is invalid. You can also check the result to determine what the schema of the resultset that is returned would be (i.e. no schema = not a SELECT statement).
Update:
In general terms when dealing with SQL that you want to protect against SQL injection there are other things you should be thinking about:
Avoid dynamic sql (concatenating user-entered values into an SQL string to be executed). Use parameterised SQL instead.
Encapsulate the query as a nested query. e.g.
SELECT * FROM (SELECT Something FROM ADynamicQueryThatsBeenGenerated) x
So if the query contains multiple commands, this would result in an error. i.e. this would result in an invalid query when encapsulated as a nested query:
SELECT SomethingFrom FROM MyTable;TRUNCATE TABLE MyTable

Related

How to prevent sql injection in dynamic SQL

This is a old topic, but I am still having problem with it, so want to get some new idea here.
I used to check | in parameter, but it seems now ; is a separator to check too.
It suggests to use sp_executesql with parameters to prevent SQL injection, but I am not sure if I can do that.
What I try to do is collect filters from client side and run dynamic SQL to get result, for example, from client side, I could send a request with the below filters to SQL:
id=1234 name=david date=2014/01/01
I will create dynamic sql like
select *
from members
where id = 1234
and name like 'david%'
and crea_date = '2014/01/01'
The search column could be any random list of field of a table, so I cannot run sp_executesql like
sp_executesql N'select * from members where id=#id and name like #name and crea_date=#crea_date',N'#id int,#name nvachar(100),#crea_date datetime', ....
Any suggestions?
You can use parameters, no problem. Make the SQL dynamic, but make the generated SQL refer to parameters. Unconditionally pass in a #name parameter if you need to, just make the name like #name part of your where clause dynamic. If you don't search on name, simply ignore the parameter in your SQL.
If you do not want to hard code the parameter names, name them param1, param2 etc.
Depending on how you are executing it, you may even be able to get rid of the dummy parameters when you aren't using them.
Default answer: Use prepared statements.

SQL query about stored procedure parameter

I wanted know the reason, when we create a stored procedure in update, delete or insert like
update TABLE_NAME set column_name = #variable_name
it is fine.
Why can't we pass parameter or variable to select like
select #column_variable from #table_variable
I know that as a work around you need to use dynamic SQL, but what is reason it won't work?
If this is about SQL Server, then the reason why you cannot parametrise column names and table names with this statement,
select #column_variable from #table_variable
is because this can already be a valid statement and interpreted in a different way:
#name would be interpreted as a reference to a scalar variable whose value is to be returned as a dataset column;
#name would be interpreted as a table variable name, i.e. the name of a variable of a table type.
In each of these cases, the use of #name to denote a parameter holding the name of an actual column or table to select from would simply be very confusing.
On the other hand, one might think that a different syntax could have been devised for this (i.e. specifically for parametrisation of names) and yet it hasn't.
My opinion (and I have to admit that it's just my opinion) why there isn't such a syntax is that by building parametrisable names into SQL you would probably end up with less efficient query planner. If at the time of query compilation you don't know what and whence the query is trying to select, you can't really build a really efficient plan for it, can you.
Of course, building a query plan could have been delayed until the time when the name parameters have been evaluated, but the planner would have had to build a plan every time such a query is invoked, unlike now, when the query plan is stored once and then used many times.

Prepare a syntactically invalid query

I want to check the syntax of a SQL query. I thought to do in preparing it, with DbCommand.Prepare method.
Unfortunately, no error or exception.
For example: SELECT * FORM table
Is there a way to check the syntax without executing the query ?
To make it perfect, it has to work on SQL Server, Oracle and IBM DB2
For SQL Server, you can use SET FMTONLY and/or SET NOEXEC
set fmtonly on
go
SELECT * FORM table
go
set fmtonly off
Generally only the database you're using is going to know whether a given query is valid or not. One standard and portable trick is to add a WHERE clause that guarantees nothing will be done, then execute the query; for example execute SELECT * FORM table WHERE 1=0 and see what happens.

Do I have to write the "GO" word in order to execute an SQL server statement?

I have little to no experience with TSQL and SQL Server - so in MySQL when I want to execute a statement I simply write:
Select * from users
...and then hit ENTER.
However now I see many SQL Server tutorials that you have the GO word immediately after each statement. Do I have to write this? For example:
Select * from users; GO
Or I can simply write:
Select * from users; <enter key pressed...>
In SQL Server, go separates query batches. It's optional in most situations.
In earlier versions of SQL Server, you had to do a go after altering a table, like:
alter table MyTable add MyColumn int
go
select MyColumn from MyTable
If you didn't, SQL Server would parse the query batch, and complain that MyColumn didn't exist. See MSDN:
SQL Server utilities interpret GO as a
signal that they should send the
current batch of Transact-SQL
statements to an instance of SQL
Server. The current batch of
statements is composed of all
statements entered since the last GO,
or since the start of the ad hoc
session or script if this is the first
GO.
GO separates batches, as Andomar wrote.
Some SQL statements (e.g. CREATE SCHEMA) need to be the first or only statements within a batch. For example, MSDN states
The CREATE PROCEDURE statement cannot
be combined with other Transact-SQL
statements in a single batch.
Local variables are also limited to a batch, and therefore are not accessible after a GO.
Go is optional, no need to write that in your sql statements.
You don't have to. What the GO will do is execute each statement (at least in Sql Server)
As the other answerers said before me, you don't really NEED Go.
There is only one case when you have to use it, and that's when you want to create a table or view and then select from it.
For example:
create view MyView as select * from MyTable
go
select * from MyView
Without Go, Sql Server won't execute this because the select statement is not valid, because the view doesn't exist at that moment.

multiple select statements in single ODBCdataAdapter

I am trying to use an ODBCdataadapter in C# to run a query which needs to select some data into a temporary table as a preliminary step. However, this initial select statement is causing the query to terminate so that data gets put into the temp table but I can't run the second query to get it out. I have determined that the problem is the presence of two select statements in a single dataadapter query. That is to say the following code only runs the first select:
select 1
select whatever from wherever
When I run my query directly through SQL Server Management Studio it works fine. Has anyone encountered this sort of issue before? I have tried the exact same query previously on similar databases using the same C# code (only the connection string is different) and had no problems.
Before you ask, the temp table is helpful because otherwise I would be running a whole lot of inner select statements which would bog down the database.
Assuming you're executing a Command that's command type is CommandText you need a ; to separate the statements.
select 1;
select whatever from wherever;
You might also want to consider using a Stored Procedure if possible. You should also use the SQL client objects instead of the ODBC client. That way you can take advantage of additional methods that aren't available otherwise. You're supposed to get better perf as well.
If you need to support multiple Databases you can just use the DataAdapter class and use a Factory o create the concrete types. This gives you the benefits of using the native drivers without being tied to a specific backend. ORMS that support multiple back ends typically do this. The Enterprise Library Data Access Application Block while not an ORM does this as well.
Unfortunately I do not have write access to the DB as my organization has been contracted just to extract information to a data warehouse. The program is one generalized for use on multiple systems which is why we went with ODBC. I suppose it would not be terrible to rewrite it using SQL Management Objects.
ODBC Connection requires a single select statement and its retrieval from SQL Server.
If any such functionality is required, a Hack can do the purpose
use the query
SET NOCOUNT ON
at the top of your select statement.
When SET NOCOUNT is ON, the count (indicating the number of rows affected by a Transact-SQL statement) is not returned.
When SET NOCOUNT is OFF, the count is returned. It is used with any SELECT, INSERT, UPDATE, DELETE statement.
The setting of SET NOCOUNT is set at execute or run time and not at parse time.
SET NOCOUNT ON mainly improves stored procedure (SP) performance.
Syntax:
SET NOCOUNT { ON | OFF }