I'm having an issue with the following code:
DECLARE #table varchar(50), #value int
SET #table = 'randomTable'
EXEC('SELECT #value = exercicio FROM '+#table+' WHERE cod = 2')
I need to do a couple of operations like that one above in some random tables. I want to select a value and store in a variable previously declared. But when I tried to execute that code, I received the following message:
Must declare the scalar variable "#value".
I'm out of ideas. Any suggestions?
The #value variable is outside the scope of the dynamic SQL statement. You'll need to return the value as an output parameter:
DECLARE
#table nvarchar(251) = N'dbo.randomTable'
, #SQL nvarchar(MAX)
, #value int;
SET #SQL = N'SELECT #value = exercicio FROM '+#table+N' WHERE cod=2';
EXEC sp_executesql #SQL, N'#value int OUTPUT', #value OUT;
Related
In T-SQL, if I wanted to reuse the same query but just update the value of the nested variable, how can I accomplish this? I have tried both examples below, however, instead of yielding an ID, both return a null value.
I am currently writing a script to populate a significantly reduced-sized database, that contains all of the same tables that the original database had, and is entirely composed of mock data for testing purposes. With that being said, I need to grab IDs from various type tables, as well as, various other data from other tables that need to be linked to one another. In order to do this, it would be great if I could reuse the same query by passing new values into the nested variable(s).
Ideally, I would love to write a function where I can call that function and just pass in different values for the parameters. Is there any way that I can do this?
NOTE: I am using Microsoft SQL Server
First:
DECLARE #var1 varchar(20);
DECLARE #queryTable int = (SELECT ID FROM dbo.Table WHERE [Name]=#var1);
SET #var1 = 'CellPhone';
SELECT #queryTable;
SET #var1 = 'HomePhone';
SELECT #queryTable;
Second:
DECLARE #var1 varchar(20);
DECLARE #queryTable int = (SELECT ID FROM dbo.Table WHERE [Name]=#var1);
SET #var1 = 'CellPhone';
DECLARE #queryTable_CellPhone INT = (SELECT (#queryTable));
SET #var1 = 'HomePhone';
DECLARE #queryTable_HomePhone INT = (SELECT (#queryTable));
SELECT #queryTable_CellPhone;
SELECT #queryTable_HomePhone;
One way is to use sp_executesql and output variable:
DECLARE #sql NVARCHAR(MAX)=
N'SELECT #query_table = ID FROM dbo.Table WHERE [Name]=#var1';
DECLARE #query_table INT, #va1 VARCHAR(100);
SET #var1 = 'CellPhone';
EXEC sp_executesql #sql,N'#query_table INT OUTPUT, #var1 VARCHAR(100)',
#query_table OUT, #var1;
SELECT #query_table;
SET #var1 = 'HomePhone';
EXEC sp_executesql #sql,N'#query_table INT OUTPUT, #var1 VARCHAR(100)',
#query_table OUT, #var1;
SELECT #query_table;
DBFiddle Demo
And without intercepting result:
DECLARE #sql NVARCHAR(MAX)= N'SELECT ID FROM dbo.Tab WHERE [Name]=#var1';
DECLARE #var1 VARCHAR(100);
SET #var1 = 'CellPhone';
EXEC sp_executesql #sql, N'#var1 VARCHAR(100)', #var1;
SET #var1 = 'HomePhone';
EXEC sp_executesql #sql, N'#var1 VARCHAR(100)', #var1;
DBFiddle Demo2
How to pass table name dynamically to the stored procedure or a simple SQL query, then store the results in a variable?
You may looking for something like this ?
USE [master]
GO
DECLARE #sql NVARCHAR(2000)
DECLARE #TableName NVARCHAR(100) ='sys.tables'
DECLARE #RecordCount INT
SET #sql = N' SELECT #RecordCountOut = COUNT(*)
FROM ' + #TableName + ' AS t'
EXEC sp_executesql #sql, N'#RecordCountOut INT OUTPUT', #RecordCountOut = #RecordCount OUTPUT
SELECT #RecordCount
You could stored your SQL query result in this way
DECLARE #Result NVARCHAR(MAX)
SELECT #Result = COLUMN FROM TableName
however, you could use print command to check what the query return
print #Result
I have a problem when I would like to transfer the value of a variable to another variable.
declare #column varchar(255);
set #column = 'cheesecake';
declare #tmp varchar(255);
set #tmp = (select #column from TEST where id = 1);
But in this case #tmp won't have the value of the table, but the name of the #column variable. I tried it with dynamic sql, but I got a syntax error.
declare #column varchar(255);
set #column = 'cheesecake';
declare #tmp varchar(255);
set #tmp = exec('select ' + #column + ' from TEST where id = 1');
How can I solve that the #tmp variable would contain the value of the query?
EXEC executes in a different context, therefore the variables cannot be shared without hassle. You specify an output parameter to the statement using sp_executesql
DECLARE
#language nvarchar(255),
#translation nvarchar(255),
#statement nvarchar(255)
SET #language = N'norwegian'
SET #statement = 'select #translation='+#language+' from Translations where id = 1'
EXEC sp_executesql
#statement,
N'#translation nvarchar(255) OUTPUT',
#translation OUTPUT
SELECT #translation
SQLFiddle
AFAIK, it is not possible to directly assign to a variable using `exec. A workaround to your issue would be to create a table variable to store the results of the dynamic query, and then set the value of the second variable using the table variable, like so:
declare #column varchar(255);
set #column = 'cheesecake';
declare #tmp varchar(255);
declare #query nvarchar(255) = N'select ' + #column + N' from TEST where id = 1'
declare #tbl table(tmp varchar(255)) --Intermediate Table variable
insert into #tbl --Insert dynamic query results here
exec sp_executesql #query
select top 1 #tmp = tmp from #tbl --Assign value here
select #tmp
EDIT: I stand corrected. This answer shows how you can assign from dynamic SQL result to a variable by making use of OUTPUT parameters within the dynamic query.
i using the dynamic query to pass the variables
select a.TableName, COUNT(a.columnvalue) as '+'count'+' from Settings a
where a.ColumnValue in ('+ #columnvalue +') and a.Value in (' + #value +')
the #columnvalues = 'a','b','c'
#value ='comm(,)','con(:)'
how to pass this in dynamic query
any idea???
I would use the sp_executesql command.
Some more documentation is here: http://msdn.microsoft.com/en-us/library/ms188001.aspx
Basically, you define a sql query, and parameter list, and then pass those in along with your actual parameters into that method.
So, something like this (real basic)
CREATE PROCEDURE dbo.yourProc
#customerId INT
AS
DECLARE #sql NVARCHAR(1000)
SET #sql = 'SELECT * FROM Customers WHERE CustomerId = #customerId'
DECLARE #params NVARCHAR(1000)
SET #params = '#customerId INT'
EXEC dbo.sp_executesql #sql, #params, #customerId
my sql statement is something like this below
DECLARE #OLD_NAV_VALUE AS INT
DECLARE #FINAL AS INT
SELECT #OLD_NAV_VALUE = [col1] from TBL_BA where DATE = #id_Date
SET #FINAL = #OLD_NAV_VALUE * 50
But the problem i am haveing here is that the column name in the select statement which is given as [col1] is a dynamic value. So i am trying something like this below.
DECLARE #OLD_NAV_VALUE AS INT
DECLARE #FINAL AS INT
EXEC('SELECT #OLD_NAV_VALUE = [' + #DYNAMIC_COL_NAME + '] from TBL_BA where DATE = ' + #id_Date)
SET #FINAL = #OLD_NAV_VALUE * 50
this gives an error that #OLD_NAV_VALUE has to be declared. So i tried declaring #OLD_NAV_VALUE inside the EXEC statement. But if i do this i am not able to use the same outside the EXEC statement.
Please let me know how to do this.
You can also use the sp_executesql statement with an output parameter:
declare #field nvarchar(50);
set #field = N'FieldToSelect';
declare #sql nvarchar(3000);
declare #parmDefinition nvarchar(500);
SET #parmDefinition = N'#returnValueOUT nvarchar(50) OUTPUT';
set #sql = N'SELECT #ReturnValueOUT = ' + #Field + ' FROM [TableName] WHERE [SomeCondition]'
declare #returnValue nvarchar(50);
EXECUTE sp_executesql #sql, #parmDefinition, #returnValueOut = #returnValue OUTPUT;
SELECT #returnValue
First, I'd suggest that you do a Google on "Erland dynamic SQL" and read his white paper on the subject.
Your design is probably not the best if it requires that you use a dynamic column name like this.
The reason that you can't do what you're trying to do is that everything in the EXEC is entirely in its own scope. If you absolutely have to do it this way though then you could use a table (either a normal table, or a global temporary table) to store the value for use outside of the EXEC.
We've used sp_executesql. Here's another example of a parameterized record count:
DECLARE #sql AS nvarchar(MAX)
SET #sql = N'SELECT #RecordCount = COUNT(*) FROM [{#SchemaName}].[{#TableName}]'
SET #sql = REPLACE(#sql, '{#SchemaName}', #SchemaName)
SET #sql = REPLACE(#sql, '{#TableName}', #TableName)
DECLARE #RecordCount AS int
EXEC sp_executesql
#query = #sql,
#params = N'#RecordCount INT OUTPUT',
#RecordCount = #RecordCount OUTPUT
This worked for me.
I declared a temp table and used it to receive the values from the select statement.
Something like below.
declare #i int
declare #v int
create table #t (val int)
insert into #t
exec ('declare #i int set #i = 0 select #i+1')
select * from #t