Parsing T-SQL statements
I am making a SQL script editor / executor component for my application, very similar in nature to the SQL Server Management Studio or ye old Query Analyzer. I'm using C#, .NET Framework 3.5 SP1. My issue is that I would like to have the component parse the SQL to determine whether it should use SqlCommand.ExecuteNonQuery(), SqlCommand.ExecuteScalar(), or SqlDataAdapter.Fill(dataTable) to run the script. The purpose is to allow the user to execute non-queries but also return result sets for the user to view, just like the SSMS / Query Analyzer would do, but also hide the ADO.NET implementation details from them.
I would normally default to SqlDataAdapter.Fill(dataTable) and always return the DataTable for the user to view. This would still run non-queries as ExecuteNonQuery would do, but it has the overhead of using the slower SqlDat开发者_如何学PythonaAdapter class to run things. This is not optimal in many non-query situations.
The approach I've taken is to allow the user to select the result type, either 'Table' (which will run SqlDataAdapter.Fill(...), 'Value' (which will run ExecuteScalar), or 'None' (which will run ExecuteNonQuery). But I don't want them to be exposed to the ADO.NET implementation details. I want them to just type a SQL script in a text box, hit an Execute button, and the program will run the script and return a result set in a datagrid if there is one.
So... I need the component to be able to parse the SQL before executing it, to discern whether there will be a result set from running the script or not.
Yo don't parse the text, since you don't have the information necessary in the client to determine if the requests would return a result. Take a requests like execute usp_anonymousProcedure 1,2;
, can you tell if it returns a result or not? Obviously, not. So you send the request to the server and ask it to just return the metadata about the result:
SET FMTONLY ON;
Returns only metadata to the client. Can be used to test the format of the response without actually running the query.
You set this on, run request your request on the server, then you'll know the shape of the result returned by the request.
Why not just execute the SQL using ExecuteReader?
The IDataReader will contain zero or more result sets.
You can iterate through the result sets, and load each one into a DataTable using DataTable.Load(IDataReader) - or just use the IDataReader/IDataRecord members to get the column names and data.
I don't see what advantage you gain by knowing the shape of the result set(s) in advance, and I'm pretty sure existing script executors like Query Analyzer don't do this.
精彩评论