SQL "if exists..." dynamic query - sql

Suppose I have a query stored in a variable like this (it's actually dynamically populated and more complex, but this is for demonstration purposes):
DECLARE #Query VARCHAR(1000) = 'SELECT * FROM dbo.MyTable'
Is there a way to check if the query would return any results? Something like this, but this doesn't work:
IF EXISTS (#Query)
BEGIN
-- do something
END
The only way that I can think of to do this is to put the results in a temp table and then query from that, but that is not ideal because the columns in the dynamic query can vary and I really don't need the temp table at all for any reason other than checking whether some rows would be returned. Is there a better way?

Try Executing the Dynamic query and use ##RowCount to find the existence of rows.
DECLARE #Query NVARCHAR(1000) = 'SELECT * FROM [dbo].[Mytable]',
#rowcnt INT
EXEC Sp_executesql #query
SELECT #rowcnt = ##ROWCOUNT
IF #rowcnt > 0
BEGIN
PRINT 'row present'
END

Try this:
DECLARE #Query NVARCHAR(1000) = 'SELECT #C = COUNT(*) FROM dbo.MyTable'
DECLARE #Count AS INT
EXEC sp_executesql #Query, N'#C INT OUTPUT', #C=#Count OUTPUT
IF (#Count > 0)
BEGIN
END

I know this answer is too late. but, I'm leaving this here to help someone else to use IF EXISTS with a dynamic query.
This is how you should do it with dynamic queries.
DECLARE #Query VARCHAR(MAX)
SET #Query = 'SELECT * FROM [dbo].[MyTable]'
SET #Query = 'IF EXISTS (' + #Query + ')
BEGIN
-- do something
print ''1''
END
ELSE
BEGIN
-- do something else
print ''0''
END
'
exec (#Query)
Hope this helped someone. Vote if it did :)

You can use EXEC to execute sql statement, then call ##ROWCOUNT which Returns the number of rows affected by the last statement, to check row exists in sql select stetement.
DECLARE #Query VARCHAR(1000) = 'SELECT * FROM dbo.MyTable',#hasRow int
EXEC (#Query)
SELECT #hasRow =##ROWCOUNT // Returns the number of rows affected by the last statement
PRINT #hasRow
IF #hasRow > 0
BEGIN
Print 1
END
BEGIN
Print 2
END

Hi I think that only way is to put IF EXISTS part into code of execution. My case is to stop execution in point when select affects at least one row, that is goal of IF EXISTS.
Little example that saves reading all records covering by condition to first occurence:
set nocount off;
drop table if exists #temp
go
create table #temp (idCol int identity(1,1),someText nvarchar(1))
go
insert into #temp values ('a')
go 25000
declare #query nvarchar(max)
,#resultFork bit
set #query = 'if exists (select * from #temp where idCol % 3 = 0)
set #resultFork=1
else
set #resultFork=0'
print #query
exec sp_executeSQL #query, N'#resultFork int output', #resultFork=#resultFork output
print #resultFork
/*Now U can use #resultFork in simple if condition...
if #resultFork = 1
begin
--
end
else
begin
--
end
*/

Related

Execute dynamic query only to get affected row count

I want to execute a dynamic query to get the affected row count. But SQL Result pane returns me the result after executing it. How to avoid returning the columns. I tried the below way.
DECLARE #Command NVARCHAR(MAX)= 'SELECT * FROM Product WHERE ID = 12'
DECLARE #Count AS INT
EXEC sp_executesql #Command, N'#C INT OUTPUT', #C=#Count OUTPUT
IF (#Count > 0)
BEGIN
EXECUTE (#Command)
END
ELSE
BEGIN
DECLARE #CatalogProduct VARCHAR(MAX) = 'SELECT p.ManufactureCode,p.PartNo,p.Size,p.ID AS ProductID,p.Name ,p.ParentProductID,p.BasePrice FROM Product.Product p WHERE p.ThruDate > GETDATE() '+#Where
EXECUTE (#CatalogProduct)
END
END
I want to avoid returning the null column set from the above attached image.
You can turn off the display, but I think a better approach is to get the count you want directly:
DECLARE #Command NVARCHAR(MAX)= 'SELECT * FROM Product WHERE ID = 12';
DECLARE #count AS INT;
DECLARE #CntCommand NVARCHAR(MAX);
SET #CntCommand = 'SELECT #count = COUNT(*) FROM (' + #Command + ') x)';
EXEC sp_executesql #CntCommand, N'#count INT OUTPUT', #count=#count OUTPUT;
Why not simply?
IF (SELECT COUNT(*) FROM Product = 12) > 0 BEGIN...
I can't see why the COUNT statement needs to be dynamic; there's nothing dynamic about it.
Also, having the SQL '... WHERE p.ThruDate > GETDATE() '+#Where is a terrible idea. If #where is a parameter it'll be wide open to SQL injection.
Try this one. Returns number of rows affected by the last query:
select ##Rowcount
DECLARE #Command NVARCHAR(MAX)= 'SELECT * FROM Product WHERE ID = 12'
DECLARE #CountCommand NVARCHAR(MAX)= 'SELECT #Count=count(1) FROM Product WHERE ID = 12'
DECLARE #Count AS INT
EXEC sp_executesql #CountCommand , N'#Count INT OUTPUT', #Count=#Count OUTPUT
IF (#Count > 0)
BEGIN
EXECUTE (#Command)
END
ELSE
BEGIN
DECLARE #CatalogProduct VARCHAR(MAX) = 'SELECT p.ManufactureCode,p.PartNo,p.Size,p.ID AS ProductID,p.Name ,p.ParentProductID,p.BasePrice FROM Product.Product p WHERE p.ThruDate > GETDATE() '+#Where
EXECUTE (#CatalogProduct)
END
END

SQL Server - Assign value to variable inside Dynamic SQL

I wanted to assign value to out variable inside a dynamic query.
SET #query = 'IF EXISTS(Condition)
BEGIN
--Some action goes here
SET #result= 1
END
ELSE
BEGIN
SET #result= 2
END'
EXEC(#query)
When am trying to execute this query, I am getting an error:
Must declare the scalar variable "#result".
How can I set value to variable inside dynamic query?
Thanks in advance.
Just try this:
DECLARE #result INT
,#query NVARCHAR(MAX);
SET #query = 'IF (1 = 0)
BEGIN
--Some action goes here
SET #result= 1
END
ELSE
BEGIN
SET #result= 2
END';
EXEC sp_executesql #query, N'#result INT OUTPUT',#result = #result OUTPUT
SELECT #result;
You can use sp_executesql in order to execute dynamic T-SQL statement and initialize SQL variables. In the sp_executesql you need to pass the parameter definition and then parameter mappings.
When you Execute a Query String, It is Considered as a separate session, so The variables that you have declared in the current windows won't be accessible whereas you can access the Temporary tables.
So you have to declare the variable inside the string. Your Query can be re-written as below
SET #query = '
DECLARE #result INT
IF EXISTS(Condition)
BEGIN
--Some action goes here
SET #result= 1
END
ELSE
BEGIN
SET #result= 2
END'
EXEC(#query)
Or Store the result in a table variable and access it from there
DECLARE #Tablevar TABLE
(
Result INT
)
SET #query = '
IF EXISTS(Condition)
BEGIN
--Some action goes here
select 1
END
ELSE
BEGIN
SELECT 2
END'
INSERT INTO #Tablevar
EXEC(#query)
select #Result = Result FROM #Tablevar

Build select statement dynamically and use it to populate a stored procedure variable

I am trying to get count of a rows with specific values in a table, and if the count is 0, then add a value in the table. This count is a local variable in stored procedure.
I am building the SQL dynamically and storing SQL statement into a nvarchar variable.
Then, using EXEC I am running this SQL as follows hoping to populate count variable.
But it's not working.
DECLARE #qry NVARCHAR(max)
DECLARE #count INT
-- building #qry will result as follows
#qry = SELECT #count = COUNT(*) FROM aTable WHERE (col1 = #col1 AND ...)
#count = EXEC #qry
IF #count = 0
BEGIN
-- carry on with adding
END
In your sql ,why you are execute your query through EXEC because of your required output is already in #count variable so it is not need in your case.
Please refer below syntax.
DECLARE #qry Numeric
DECLARE #count INT
-- building #qry will result as follows
SELECT #count = COUNT(*) FROM aTable WHERE (col1 = #col1 AND ...)
IF #count = 0
BEGIN
-- carry on with adding
END
If you are building the query dynamically, you need sp_executesql. Try something like
-- building #qry will result as follows
#qry = 'SELECT #count = COUNT(*) FROM aTable WHERE (col1 = #col1 AND ...)'
EXEC sp_executesql #qry, N'#count INT OUTPUT', #count OUTPUT;
--Do whatever you want with #count...
Source: Aaron Bertrand's answer here and sp_executesql explanation..
I think #qry needs to be a string for executing, not the result of the select, like so:
DECLARE #qry NVARCHAR(max);
DECLARE #count INT;
-- building #qry will result as follows
SET #qry = 'SELECT COUNT(*) FROM aTable WHERE (col1 = #col1 AND ...)';
SET #count = exec #qry;

return null instead of nothing if there are no results

I have a dynamic sql statement that may or may not return any results. For simplicity sake:
--other SQL statements defining #a
DECLARE #sql varchar(128)
SELECT #sql = 'SELECT a, b FROM c WHERE a = ' + #a
EXEC(#sql)
I want the results if this statement returns any but if EXEC(#sql) does not return any results how can I go about making it return a single null instead?
I am working with MS SQLServer 2000.
EXPLANATION FOR X-ZERO
This is for use in a webapp ajax response. I am not able to alter the backend java framework which requires a resultset of some kind to be returned by the query to the webservice.
SOLUTION
In case anyone else has this question and because it wasn't totally clear in the answers, this worked:
--other SQL statements defining #a
DECLARE #sql varchar(128)
SELECT #sql = 'SELECT a, b FROM c WHERE a = ' + #a
EXEC(#sql)
IF ##ROWCOUNT = 0 SELECT null
You can get the result set record count of the statement with the same WHERE clause, and it it is zero, then you can just return one record with null value.
Example:
declare #sql varchar(128)
declare #a varchar(10);
set #a = '''Some #a value''';
declare #rowcount int;
exec sp_executesql N'select #rowcount=count(*) FROM c WHERE a = ''Some #a value''',
N'#rowcount int output', #rowcount output;
if #rowcount <> 0
begin
select #sql = 'SELECT a, b FROM c WHERE a = ' + #a
end
else
begin
select #sql = 'select null';
end
exec(#sql) ;
Hope this helps you!
If I understand your question, you want the statement to return a single row consisting of null when no rows are returned from the actual query. Or, put another way, you want it to return a value (null) when it's supposed to return no values.
I think what you should do instead is leave the query as-is and get a count of the number of rows returned by the statement. I believe you can do this with the ##rowcount variable after doing the query.
(Disclaimer: What I know about SQL Server I learned from Google and S.O.)
Another option avoiding ##ROWCOUNT would be to save the results in a table variable, then return the results if any exist or NULL if they don't. E.g:
DECLARE #results TABLE(a int, b int)
DECLARE #sql nvarchar(128)
SELECT #sql = 'SELECT a, b FROM c WHERE a = ' + #a
insert into #results
exec (#sql)
IF EXISTS(select top 1 * from #results)
SELECT * from #results
ELSE SELECT null
Look at the SQL Docs on MAX(Transact-SQL). "MAX returns NULL when there is no row to select.". I should give credit to this answer on SqlServerCentral.
DECLARE #sql VARCHAR(128)
SET #sql = 'SELECT MAX(a), MAX(b) FROM c WHERE a = ' + #a
EXEC SP_EXECUTESQL #sql

Assign db query value to t-sql variable in dynamic query

I have this requirement to be implemented in a stored procedure. Dynamically query the database to get the count of a table, store it in a t-sql variable and then take some decisions based on that.
This is the stored procedure that i am working on . This is throwing some errors as i don't think there is a simple way of assigning the result of a tsql dynamic query to a variable.
CREATE PROCEDURE test
AS
BEGIN
DECLARE #sql VARCHAR(255)
DECLARE #cnt int
SET #sql = 'SELECT COUNT(1) FROM myTable'
SET #cnt = EXEC(#sql)
IF (#cnt > 0)
PRINT 'A'
ELSE
PRINT 'B'
END
GO
Could someone tell me if there is a simpler way of achieving this using T-SQL ?
Thanks.
alternative:
declare #tablename varchar(512) = 'sometable'
declare #sql nvarchar(512) = 'set #count = (select count(*) from ' + #tablename + ')'
declare #count int
execute sp_executesql #sql, N'#count int output', #count=#count output
select case when #count > 0 then 'A' else 'B' end
Try this:
SET #sql = 'SELECT #cnt = COUNT(1) FROM myTable'
EXEC(#sql)