Don't display dynamic query in result - sql

Is it possible to hide a dynamic query from the result sets provided from a Stored Procedure?
I am using the ##rowcount of the dynamic query to set a variable that is used to determine whether another query runs or not.
The other query is used by code that I cannot change - hence why I am changing the Stored Procedure. The dynamic query returns as the first result set from the Stored Procedure is now the result of the dynamic query which currently is "breaking" the calling code.
Thanks in advance

I have managed to solve this by inserting the result of the dynamic query into a temporary table and then retrieving the rowcount from the temporary table.
-- Create query
declare #query nvarchar(max)
set #query = 'select ' + #entityname + 'id from ' + #entityname + ' where ' + #entityname + 'id = ' + cast(#entityid as nvarchar(100))
-- Insert into to temp table - no new result set displayed!
declare #tbl table (EntityID int not null primary key)
insert into #tbl
exec (#query)
-- Retrieve variable from temporary table
declare #count int
select #count = count(*) from #tbl
Above is the code I ended up using.

Try wrapping the dynamic query like this:
Set #query = 'SELECT COUNT(*) FROM (' + #Query + ') t'

Related

How can I create a dynamic Select statement within a SQL Select statement?

I have a SELECT statement that can produce a list of values:
DECLARE #ValueList varchar(Max);
SELECT #ValueList = COALESCE(#ValueList + ',', '') + CAST(Val AS varchar(max))
FROM
(SELECT TOP (100) PERCENT tblSampleTable.SomeIDNumber AS Val
FROM tblSampleTable) AS ValuesThisYear
PRINT #ValList
This returns a list with values something like
val1,val2,val4,val9,
etc., ehich I can then feed into a stored procedure, or manage some other way.
Now I want to have the query that gets assessed for the list of values to be dynamic, maybe passed in or from another stored procedure, similar to this:
DECLARE #ValueList varchar(Max);
DECLARE #TSQL varchar(Max);
SET #TSQL = {stored proc to get base query}
SELECT #ValueList = COALESCE(#ValueList + ',', '') + CAST(Val AS varchar(max))
FROM
(#TSQL) AS ValuesThisYear
PRINT #ValList
I know that's the wrong syntax for including #TSQL, and that's what I'm trying to find out. I've viewed a number of threads and tried a number of methods, but am still not able to incorporate this dynamic part.
The tricky part seems to be the making of the list (the COALESCE and CAST statements), where I incorporate #ValList as part of the returned string.
Any help would be appreciated!
Dynamic SQL is usually about
Creating a variable that contains the exact SQL you want to run
Then using EXEC (#SQLvariable) to run that code
For example (not for production yet!) I've added a new variable #CustomSQL
DECLARE #ValueList varchar(Max);
DECLARE #TSQL varchar(Max);
DECLARE #CustomSQL varchar(Max);
SET #TSQL = {stored proc to get base query}
SET #CustomSQL =
'SELECT COALESCE(#ValueList + '','', '''') + CAST(Val AS varchar(max))
FROM (
' + #TSQL + '
) As ValuesThisYear;'
PRINT #CustomSQL
EXEC (#CustomSQL)
Notice that adding text/strings (e.g., the #TSQL variable) have to be entered as exact strings rather than their variable names. Also note apostrophes - you need to use '' every time you wish to refer to a '.
I also removed the variable name from the SELECT #ValueList = ... because the dynamic SQL cannot actually reference the variables - it has its own scope (?cannot remember the correct word) and doesn't have access to the variables. Solutions to this include
Using a temporary table e.g., #temp which can be referenced
Using the OUTPUT clause
Personally, I would approach it a different way - use the T-Sql provided to put data into a temporary table. Then use the temporary table in the other statement e.g.,
DECLARE #ValueList varchar(Max);
DECLARE #TSQL varchar(Max);
SET #TSQL = {stored proc to get base query}
DECLARE #CustomSQL varchar(Max)
CREATE TABLE #temp (Val varchar(1000))
SET #CustomSQL = 'INSERT INTO #temp (Val) ' + #TSQL
EXEC (#CustomSQL)
SELECT #ValueList = COALESCE(#ValueList + ',', '') + CAST(Val AS varchar(max))
FROM #temp As ValuesThisYear;
PRINT #ValList
I almost never get my dynamic SQL correct first try. Suggestions
Keep it as simple as possible
Before having a version that runs (e.g., EXEC (#CustomSQL)), comment the EXEC out and PRINT it instead.
Here are some examples from previous posts I've done recently
Query for R Machine Learning Services - Filtering Categories in Where Clause
Bottom of Dynamic columns depend on previous dynamic columns - TSQL

Generating filed name with concat

My table has column names m1,m2,m3...,m12.
I'm using iterator to select them and insert them one by one in another table.
In this iterator I'm trying to generate filed names with:
'['+concat('m',cast(#P_MONTH as nvarchar))+']'
where #P_MONTH is incrementing in each loop.
so for #P_MONTH = 1 this suppose to give [m1] which works fine.
But when I run query I get:
Conversion failed when converting the nvarchar value '[m1]' to data
type int.
And if I put simply [m1] in that select it works ok.
How to concat filed name so it can be actually interpreted as filed name from certain table?
EDIT
Here is full query:
DECLARE #SQLString nvarchar(500),
#P_YEAR int,
#P_MONTH int = 1
set #P_YEAR = 2018
WHILE #P_MONTH < 13
BEGIN
SET #SQLString =
'INSERT INTO [dbo].[MASTER_TABLE]
(sector,serial,
date, number, source)'+
'SELECT ' + '[SECTOR],[DEPARTMENT]' +
QUOTENAME(cast(CONVERT(datetime,CONVERT(VARCHAR(4),#P_YEAR)+RIGHT('0'+CONVERT(VARCHAR(2),#P_MONTH),2)+'01',5) as nvarchar))+
QUOTENAME ('M',cast(#P_MONTH as nvarchar)) +
'EMPLOYED' +
'FROM [dbo].[STATS]'+
'where YEAR= #P_YEAR'
EXECUTE sp_executesql #SQLString
SET #P_MONTH = #P_MONTH + 1
END
It's still not working. It executes successfully but it does nothing.
Good day,
Let's create a simple table for the sake of the explanation
DROP TABLE IF EXISTS T
GO
CREATE TABLE T(a1 INT)
GO
INSERT T(a1) VALUES (1),(2)
GO
SELECT a1 FROM T
GO
When we are using a query like bellow, the server parse the text as a value and not as a column name
DECLARE #String NVARCHAR(10)
SELECT #String = '1'
--
SELECT '['+concat('a',cast(#String as nvarchar))+']'
FROM T
GO
This mean that the result will be 2 rows with no name for the column and the value will be "[a1]"
Moreover, the above query uses the brackets as part of the string.
One simple solution is to use the function QUOTENAME in order to add brackets around a name.
Another issue in this approach is the optional risk of SQL Injection. QUOTENAME might not be perfect solution but can help in this as well.
If we need to use entities name dynamically like in this case the column name then for most cases using dynamic query is the best solution. This mean to use the Stored Procedure sp_executesql as bellow
DECLARE #String INT
SELECT #String = 1
DECLARE #SQLString nvarchar(500);
SET #SQLString =
'SELECT ' + QUOTENAME(concat('a',cast(#String as nvarchar))) + ' FROM T'
EXECUTE sp_executesql #SQLString
GO

Execute dynamic sql for all rows in a result set without a loop

I have a query that generates a query for each row in a table.
For example:
select ' create proc ['+[ProcName]+'] as
print '''+[ProcName]+''''
from MyTable
The results of this query will give me a sql statement I can execute for every row of data in the table.
CREATE PROC [proc_1]
AS
PRINT 'proc_1'
--
CREATE PROC [proc_2]
AS
PRINT 'proc_2'
etc.
Is it possible to execute every row in my result set without having to implement some form of cursor/loop?
You can concatenate all column values in sql pass variable by many ways
as examples: XMLPATH, STUFF or COALESCE, with some manipulation with string.
but still getting an error
The Main Issue for This task is Go
Go is Not-Valid T-SQL
so if you tried execute dynamic sql contains Go, the next error will be raised:-
Msg 102, Level 15, State 1, Line 4 Incorrect syntax near 'go'.
After surfing the stackoverflow , I get the resolved here:-
Execute Dynamic Query with go in sql
so Get the next demo (after applying the above link with my trials):-
Demo:-
-- Try to create 4 procedures proc_1, proc_2 , proc_3 and proc_4
Create database Demo
go
use Demo
go
Create table MyTable (procName varchar (200))
go
insert into MyTable values ('proc_1')
go
insert into MyTable values ('proc_2')
go
insert into MyTable values ('proc_3')
go
insert into MyTable values ('proc_4')
go
declare #Query nvarchar(max)
SELECT #Query = isnull(#Query,'') + 'create proc ['+[ProcName]+'] as
print '''+[ProcName]+''''+ char (10) + '
Go
'
FROM MyTable
--print #Query
SET #Query = 'EXEC (''' + REPLACE(REPLACE(#Query, '''', ''''''), 'GO', '''); EXEC(''') + ''');'
EXEC (#Query)
Result:-
you can declare a variable, store the queries (seperates) inside it and execute it
DECLARE #strQuery Varchar(MAX)
SET #strQuery = ''
select #strQuery = #strQuery +
'EXEC('' create proc [' + [ProcName] + ']
as
print ''''' + [ProcName] + '''''
'')'
from MyTable
EXEC(#strQuery)
--To view your query
PRINT(#strQuery)
Note: i used Exec command for each procedure because they cannot be executed at the same time in a query

Execute sp_executesql, Table Variabe not Declared

I am Using SQL server 2012 and i want to select random columns from my table by applying where condition in this query:
EXECUTE sp_executesql
N'SELECT *
FROM #table
WHERE #Col = #Value',
N'#Value nvarchar(44),#table nvarchar(55),#Col nvarchar(30)',
#Value = 'Cus_1',#Col='CustId',#table='SaleOrder';
But when I execute it, it shows error
Must declare the table variable "#table"
I also tried it to declare by this: #table table(Id nvarchar(30)), but thin it shows again an error on table type...
Please help
This is what you are trying to run:
EXECUTE sp_executesql
N'SELECT * FROM #table WHERE #Col = #Value',
N'#Value nvarchar(44), #table nvarchar(55), #Col nvarchar(30)',
#Value = 'Cus_1', #Col='CustId', #table='SaleOrder';
Alas. You cannot substitute in a table name or column name using parameter substitution. So, SQL Server is looking for a table variable called #table. You can fix this by putting the values directly into the string:
declare #Col = 'CustId', #table = 'SaleOrder';
declare #sql nvarchar(max) = N'SELECT * FROM ' + #table + ' WHERE ' + #Col + ' = #Value';
EXECUTE sp_executesql #sql,
N'#Value nvarchar(44)',
#Value = 'Cus_1';
Unfortunately, I cannot find a good reference in the documentation that explains what is happening. When a statement is compiled, it is allowed to have parameters. However, the parameters are for values in the statement, not for column, table, database, or UDF names or for keywords. The statement itself is compiled, with place holders for the parameters, and in order to be compiled, the SQL engine needs to resolve all object names.

How to dynamically specify a column in stored procedure

I need to write a stored procedure which will update into a particular column, based on parameters. This will be called from a C# app.
The table to be updated is like this:
TableA: Id, Col1, Col2, Col3.
Something like this:
Create Procedure UpdateByCol
#col_num int,
#value string,
#id int
as
Begin
Update TableA Set *How do I specify the column here* = #value where Id = #id
End
Declare #SQL varchar(max)
Set #SQL = 'Update ' + #TableName + ' Set ' + #Col1 + ' = ' + #Col1Val....
Exec (#SQL)
This exposes you to SQL injection though...
There is a way to do this without dynamic sql. Create individual stored procs for each column that is eligible for updating. Then, in your master stored proc, call the applicable stored proc based on the paramter received.
If you really want to do this it can be done with dynamic sql. http://technet.microsoft.com/en-us/library/ms188001.aspx
It is not good practice to do this but if you really wanted to you'd have to use dynamic sql to create the string and execute it like so:
Create Procedure UpdateByCol
#col_num int,
#value string,
#id int
as
Begin
declare #str varchar(2000)
set #str = 'Update TableA Set Col' + convert(varchar,#col) + ' = ''' + #value + ''' where Id = ' + convert(varchar, #id )
exec ( #str )
End
This is a very bad thing to do because it creates a security hole.