Can I specify a database name dynamically in a trigger? - sql-server

I need to get data from a table in a database who's database name will be determined as a variable during a trigger. I then, knowing this variable need to get a seqno from a table in the determined database for a item which was also determined as a variable during a trigger.
I am trying this route as I assume I need to build the SQL statement before I set it to a variable.
This is not working and I need to know the best way on how I can do this:
DECLARE #SU_SEQNO INTEGER, #SU_NAME VARCHAR(50), #SU_OWNER VARCHAR(15), #SUD_SEQNO INTEGER, #SQL NVARCHAR(500)
SET #SU_OWNER = 'XXX'
SET #SU_NAME = '1ABC234'
SET #SQL ='SELECT #SUD_SEQNO=SEQNO FROM ' + (#SU_OWNER) + '.SU_MAIN
WHERE UNITNAME= ' + #SU_NAME
SET #SUD_SEQNO = (EXECUTE (#SQL))
Thanks alot for any help with this

From: Get result from dynamic SQL in stored procedure
SET #SQL = N'SELECT DISTINCT #FiscalYear = FiscalYear FROM ' + #DataSource;
EXEC sp_executesql #SQL, N'#FiscalYear INT OUTPUT', #FiscalYear OUTPUT;
PRINT #FiscalYear;
I'd re-engineer to use the sp_executesql method as shown above. That should do the trick.

I have amended the code, and it works
declare #su_owner varchar(15) = 'DBTEST'
declare #SU_SEQNO INTEGER=1, #SUD_SEQNO INTEGER=0, #SQL NVARCHAR(500)
DECLARE #ParmDefinition NVARCHAR(500), #SU_NAME_INPUT VARCHAR(50)='SU123'
SET #SU_NAME_INPUT = (SELECT UNITNAME FROM SU_MAIN WHERE SEQNO=#SU_SEQNO)
SET #SU_NAME = (SELECT UNITNAME FROM SU_MAIN WHERE SEQNO=#SU_SEQNO)
SET #SQL = N'SELECT #sud_seqnoOUT=MAX(SEQNO) FROM ' + quotename(#su_owner) + '.[dbo].[SU_MAIN] WHERE UNITNAME]=#SU_NAME_INPUT' ;
SET #ParmDefinition = N'#SU_NAME_INPUT VARCHAR(50),#sud_seqnoOUT INT OUTPUT'
EXEC sp_executesql #SQL,#ParmDefinition,#SU_NAME_INPUT = #SU_NAME,
#sud_seqnoOUT = #SUD_SEQNO OUTPUT

Related

Returning Variables from Linked Servers

I need to write a stored procedure which will return the value of a parameter, acquired from a Linked Server.
I have tried declaring the variable both inside and outside of the dynamic sql but it fails with a must declare variable error.
declare #srvr nvarchar(100)
declare #dbn nvarchar(50)
set #srvr = 'ServerName'
set #dbn = 'DatabaseName'
Declare #sql nvarchar(max)
set #sql = 'declare #param nvarchar(50) set #param = (Select X from [' + #srvr + '].[' + #dbn + '].[TableName])'
exec (#sql)
print #param
This will form the framework for multiple procedures which reside in a central database, these procedures will be called when restoring other databases into the environment forming part of 'prep script' of sorts
Any ideas please?
Thanks very much
You need to declare the variable twice. Once for the inner context, once for the outer context. They need not use the same names inside and out:
declare #srvr nvarchar(100)
declare #dbn nvarchar(50)
set #srvr = N'ServerName'
set #dbn = N'DatabaseName'
Declare #sql nvarchar(max)
declare #parms nvarchar(max)
set #sql = N'set #param = (Select X from [' + #srvr + '].[' + #dbn + '].[TableName])'
set #parms = N'#param nvarchar(50) output'
declare #param2 nvarchar(50)
exec sp_executesql #sql,#parms,#param = #param2 output
print #param2

SQL server 2012 - return variable value from a dynamic script

I'm trying to run a dynamic script to then return the variable so I can pass in to the rest of my script. I've a couple of ways with the help of Google, but I think I still haven't got the syntax correct, therefore getting error or null value returned.
Can someone please advise where I've gone wrong.
For example:
To return the value for variable #table_name
ASIA is the database and this is set as variable which is appended to the table name that is retrieved from the table and T5148 is the id from the table to turn the table name as is so a variable. I have set this a variables as this script sits when other scripts which loops
Thank you
declare #table_name nvarchar(50)
declare #database nvarchar(50)
declare #id nvarchar(50)
declare #sql nvarchar(max)
set #database = 'ASIA'
set #id = 'T5178'
set #sql = N'SELECT #table_name = ''#database''+table_name
FROM ''#database''+tables (NOLOCK)
WHERE id = ''#id'''
exec sp_executesql #sql, N'#table_name nvarchar(50) output', #table_name output
select #TRAN_TABLE
If I am not wrong, this is what you need :
DECLARE #table_name NVARCHAR(50)
DECLARE #database NVARCHAR(50)
DECLARE #id NVARCHAR(50)
DECLARE #sql NVARCHAR(MAX)
SET #database = 'ASIA'
SET #id = 'T5178'
SET #sql = N'SELECT #table_name = table_name
FROM ' + #database+'.dbo.tables (NOLOCK)
WHERE id = #id'
EXEC SP_EXECUTESQL #sql, N'#id nvarchar(50),#table_name nvarchar(50) output',
#id = #id, #table_name = #table_name OUTPUT
SET #table_name = #database + #table_name
Note : change dbo as you schema name.

Dynamic Column Name in SQL in Update statement

DECLARE #sql NVARCHAR(max)
DECLARE #ParmDefinition NVARCHAR(500)
SET #sql = 'UPDATE [Table1] SET [Table1].[#columnName] = TEST';
SET #ParmDefinition = N'#columnName NVARCHAR(50)';
EXEC sp_executesql #sql, #ParmDefinition, #columnName = N'MyColumn';
When I run the above query, I get Invalid column name '#columnName'.. Clearly, the column name is not being replaced when the query is run.
In reality, my #sql variable is much larger and I have many columns I wish to update, thus I would like to avoid doing SET SQL = for all enumerations of the column name.
I'd like to declare the sql string once, and invoke the query with different values. e.g.:
EXEC sp_executesql #sql, #ParmDefinition, #columnName = N'MyColumn';
EXEC sp_executesql #sql, #ParmDefinition, #columnName = N'AnotherColumn';
EXEC sp_executesql #sql, #ParmDefinition, #columnName = N'YetAnotherColumn';
-- And so on
Is something like this possible?
Yes, you have to concatenate the variable outside the string. In other words:
SET #sql = 'UPDATE [Table1] SET [Table1].[' + #columnName + '] = t1.Value ' +
EDIT: Another solution we have used is to replace tokens in the base sql to construct a new sql variable for execution.
DECLARE #sql nvarchar(max) = 'SELECT #ColumnName FROM #TableName';
DECLARE #sql2 nvarchar(max) = REPLACE(REPLACE(#sql,'#ColumnName',#ColumnNameVariable),'#TableName',#TableNameVariable)
EXEC (#sql2)
...Some code that changes the values of #ColumnNameVariable and #TableNameVariable...
DECLARE #sql2 nvarchar(max) = REPLACE(REPLACE(#sql,'#ColumnName',#ColumnNameVariable),'#TableName',#TableNameVariable)
EXEC (#sql2)
And you'll notice that the Declaration and Exec of SQL2 are exactly the same lines in both cases. This lends itself to use in a LOOP if that is applicable. (Except that you wouldn't DECLARE #Sql2 in the loop...just populate/re-populate it).
First of all, kudos for trying to parameterize your dsql using sp_executesql. The problem is, you can only parameterize something you could put into a variable in the first place such as in a search predicate or select list.
However it's still possible; just concatenate the column name with your DSQL string, wrapping it with the quotename function
set #sql = 'update table1 set table1.' + quotename(#ColumnName) + ' = ...

How do you use OPENQUERY within sp_executesql?

I'm trying to verify a job number exists on a linked server and get back a variable (#JobExists) indicating whether it does or not (1 for yes, 0 for no).
To do this I'm trying to use OPENQUERY along with sp_executesql as I have to pass in a parameter for the job number. I've tried the code below but get the error 'Procedure expects parameter '#statement' of type 'ntext/nchar/nvarchar'. For testing purposes I've declared and set the variable #JobNumber.
DECLARE #JobNumber as varchar(50)
SET #JobNumber = '2112111'
DECLARE #JobExists as BIT
DECLARE #JobCount as int
DECLARE #ParmDefinition as varchar(100)
DECLARE #sql as varchar(500)
SET #JobExists = 0
SET #ParmDefinition = N'#Result int output'
SET #sql = 'SELECT #Result = SELECT COUNT(*) FROM OPENQUERY(MYLINKEDSVR,''SELECT JOB_NUMBER FROM PROD.tbl1 WHERE JOB_NUMBER = ''''' + UPPER(RTRIM(LTRIM(#JobNumber))) + ''''''')'
exec sp_executesql #sql, #ParmDefinition, #Result = #JobCount output
IF #JobCount > 0
SET #JobExists = 1
SELECT #JobExists
I've read up sp_executesql here: http://technet.microsoft.com/en-us/library/ms188001.aspx
I've also done various searches but haven't come across any answers that work for me.
Is there something I'm missing?
The error message is clear: you must declare #sql as nvarchar and not as varchar.
The same for #ParamDefinition:
DECLARE #ParmDefinition as nvarchar(100)
DECLARE #sql as nvarchar(500)

how to assign variable with exec string in sql?

I would like to assign a variable with what is returned from and "exec (string)" but am struggling with syntax. Below is some working code...
declare #iGeographyLevel int = 2
declare #iGeographyLevelID int = 64
declare #sGeographyName varchar(30)
declare #sSQL nvarchar(max)
set #sSQL = '
select Name
from GeographyLevel'+ cast(#iGeographyLevel as varchar(5))+'
where GeographyLevel'+ cast(#iGeographyLevel as varchar(5)) + 'ID = '+ cast(#iGeographyLevelID as varchar(5))
exec (#sSQL)
I would like to do something like...
set #sGeographyName = exec (#sSQL)
sp_executesql is the best way of doing this.
DECLARE #iGeographyLevel INT = 2
DECLARE #iGeographyLevelID INT = 64
DECLARE #sGeographyName VARCHAR(30)
DECLARE #sSQL NVARCHAR(max)
SET #sSQL = '
SELECT #sGeographyName = Name
FROM GeographyLevel' + cast(#iGeographyLevel AS VARCHAR(5)) + '
WHERE GeographyLevel' + cast(#iGeographyLevel AS VARCHAR(5)) + 'ID = #iGeographyLevelID'
EXEC sp_executesql
#sSQL,
N'#iGeographyLevelID INT, #sGeographyName VARCHAR(30) OUTPUT',
#iGeographyLevelID,
#sGeographyName OUTPUT
SELECT #sGeographyName
The requirement for dynamic SQL here is a bit smelly though. Not sure why you don't just have one Geography table with a Level column (or possibly a partitioned view if the tables must be separate) Also Hungarian notation for variable names is widely discouraged these days.

Resources