September 1, 2016 at 10:08 am
I want to be able to pass a string into a stored proc and then check to see if it is a valid TSQL statement. Does anyone know if that is possible?
John Deupree
John Deupree
September 1, 2016 at 10:28 am
The only thing that comes to my mind is sp_get_query_template.
It is used to get the parameterized form of a query, but it fails if the query is not valid.
BEGIN TRY
DECLARE @my_templatetext nvarchar(max)
DECLARE @my_parameters nvarchar(max)
EXEC sys.sp_get_query_template @querytext = N'SELECT * FROM master.sys.databases WHERE name === ''master'''''
,@templatetext = @my_templatetext OUTPUT
,@parameters = @my_parameters OUTPUT;
END TRY
BEGIN CATCH
IF ERROR_NUMBER() = 102
BEGIN
PRINT 'The statement is invalid: ' + ERROR_MESSAGE()
END
END CATCH
-- Gianluca Sartori
September 1, 2016 at 10:37 am
Another option is to use either sp_describe_first_result_set or the sys.DM... version of it.
😎
September 1, 2016 at 12:51 pm
Thanks for the reply.
Sorry this is for 2008R2. 🙁
That's new for 2012
John Deupree
September 1, 2016 at 1:00 pm
Maybe this can give you an idea.
CREATE TABLE Test( id int);
DECLARE @SQL NVARCHAR(1000) = 'DROP TABLE Test;';
EXEC( 'SET NOEXEC ON; ' + @SQL);
SELECT * FROM Test;
DROP TABLE Test;
EDIT: Changed PARSEONLY to NOEXEC. That way the statement should compile and not only parse.
September 1, 2016 at 1:23 pm
Thanks for the reply.
Co-worker gave me this code so it seems that your solution or either of these work. Only problem is that they don't check for valid objects (columns or tables) in DB.
DECLARE @cSql NVARCHAR(MAX);
DECLARE @my_templatetext NVARCHAR(MAX);
DECLARE @my_parameters NVARCHAR(MAX);
--SET @cSql = 'CREATE NONCLUSTERED INDEX idx_Fred ON xyz.Fred ( FredId ) INCLUDE (FredStatus)'
SET @cSql = 'SELECT * FROM dbo.fred'
-- uncomment this to use EXEC or sys.sp_executesql
--SET @cSql = 'set noexec on; ' + @csql
BEGIN TRY
-- either this
EXEC sys.sp_executesql
@cSql;
--or this
EXEC (@cSql);
-- or this works
EXEC sys.sp_get_query_template
@querytext = @cSql
, @templatetext = @my_templatetext OUTPUT
, @parameters = @my_parameters OUTPUT;
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER()
, ERROR_MESSAGE();
RETURN;
END CATCH;
John Deupree
September 1, 2016 at 4:25 pm
John Deupree (9/1/2016) Only problem is that they don't check for valid objects (columns or tables) in DB.
Columns are checked. If a columns does not exist sp_get_query_template throws an error.
Tables are not.
It's exactly the same way as when you create a normal stored procedure.
_____________
Code for TallyGenerator
September 1, 2016 at 4:43 pm
For some reason, the whole idea of passing a SQL statement to a stored procedure to see if it's valid makes me shudder a bit. I have to ask why you'd want to do this and if this is exposed to a front end of some type. If a rogue statement were passed to it, would it recognize that the TRUNCATE or DROP TABLE could do damage?
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply