Pass table name using parameter in SQL Server stored procedure - sql-server

I want to create a stored procedure that will update a table. The procedure will join two tables and I want to pass the table name using a variable (#tablename).
This error is generated:
Must declare the table variable "#tablename".
My code:
Create Procedure dbo.SpUpdate (#TableName varchar(50))
as
begin
set #tablename='Customer'
Update a
Set AgentNumber = '5',
From dbo.CustomerList a
join #tablename b on a.customerid = b.customerid
end

You can use this script:
Create Procedure dbo.SpUpdate (#TableName varchar(50))
as
begin
DECLARE #SqlText NVARCHAR(MAX)
SET #SqlText =
'Update a
Set AgentNumber=''5'',
From dbo.CustomerList a
join ' + QUOTENAME(#tablename) + ' b
on a.customerid= b.customerid'
EXEC sp_executesql #SqlText
end

Related

Transact SQL UPDATE based on a declared variable

I have two tables called ALUMNO and ALUMNO_GENERAL.
I would like to create a stored procedure which automatically chooses which table will update by looking at the variable #campo declared as a parameter to the stored procedure.
When I execute the procedure below, it says 1 row affected, but does not update the value of the table.
exec updateAl 'CALLE','0015','ROJO'
Stored procedure:
create procedure updateAl
#campo varchar(30), #matr varchar(10), #newVal varchar(15)
as begin
if #campo IN ('AP_PATERNO' , 'AP_MATERNO', 'NOMBRE', 'GRUPO', 'TURNO' , 'SEMESTRE' , 'STATUS' , 'NUMEMPLEADO')
begin
select #campo
declare #sql varchar (1000)
select #sql= 'update alumno set '+ #campo+'='+#newVal +' where MATRICULA='+#matr
exec(#sql)
end
else
update ALUMNO_GENERAL set #campo =#newVal where MATRICULA=#matr
end
Your dynamic sql is not correct, try this:
select #sql= 'update alumno set '+ #campo+'='''+#newVal +''' where MATRICULA='''+#matr + '''
exec(#sql)
end

Need help. Message says temp table doesn't exist: 'Invalid object name '#TempCodes'.'

If I run the select statement below by itself (with the table name hard coded in) it runs fine and the temp table is created. If I run it as below it says 'Invalid object name '#TempCodes'' although when I print #Sql1 it looks exactly the same as when I run it by itself (with the table name hard coded in).
Any ideas on what's going on here will be appreciated.
DECLARE #TableName NVARCHAR(50)
SET #TableName = '[My Table Name]'
DECLARE #Sql1 NVARCHAR(MAX);
SET #Sql1 = N'SELECT AccountNumber,LTRIM(RTRIM(m.n.value(''.[1]'',''varchar(8000)''))) AS mdcodes INTO #TempCodes FROM (SELECT AccountNumber,CAST(''<XMLRoot><RowData>''
+ REPLACE(MD_Results,'','',''</RowData><RowData>'')
+ ''</RowData></XMLRoot>'' AS XML) AS x FROM ' + #TableName
+ N')t CROSS APPLY x.nodes(''/XMLRoot/RowData'')m(n)'
IF OBJECT_ID('tempdb.dbo.#TempCodes', 'U') IS NOT NULL
BEGIN
drop table #TempCodes
END
EXECUTE sp_executesql #Sql1
Select * from #TempCodes
I believe ## is a typo. Even if you fix it to # it will throw same error.
EXECUTE sp_executesql #Sql1
A local temporary table created in a stored procedure is dropped
automatically when the stored procedure is finished.
In your case sp_executesql is the stored procedure.
the table created inside the dynamic query will be dropped after the exec sp_executesql is completed. That's why you are getting that error.
You need to create table outside and use Insert into table..select syntax inside the dynamic query
IF OBJECT_ID('tempdb.dbo.#TempCodes', 'U') IS NOT NULL
drop table #TempCodes
create table #TempCodes(AccountNumber varchar(100),mdcodes varchar(100))
SET #Sql1 = N'Insert into #TempCodes
SELECT AccountNumber,LTRIM(RTRIM(m.n.value(''.
[1]'',''varchar(8000)''))) AS mdcodes FROM (SELECT
AccountNumber,CAST(''<XMLRoot><RowData>'' +
REPLACE(MD_Results,'','',''</RowData><RowData>'') + ''</RowData></XMLRoot>''
AS XML) AS x FROM '+#TableName+ N')t CROSS APPLY
x.nodes(''/XMLRoot/RowData'')m(n)'
Try using a global temp table ##TempCodes as local temporary tables are only visible in current session.
DECLARE #TableName NVARCHAR(50)
SET #TableName = '[My Table Name]'
DECLARE #Sql1 NVARCHAR(MAX);
SET #Sql1 = N'SELECT AccountNumber,LTRIM(RTRIM(m.n.value(''.
[1]'',''varchar(8000)''))) AS mdcodes INTO ##TempCodes FROM (SELECT
AccountNumber,CAST(''<XMLRoot><RowData>'' +
REPLACE(MD_Results,'','',''</RowData><RowData>'') + ''</RowData></XMLRoot>''
AS XML) AS x FROM '+#TableName+ N')t CROSS APPLY
x.nodes(''/XMLRoot/RowData'')m(n)'
IF OBJECT_ID('tempdb.dbo.##TempCodes', 'U') IS NOT NULL
BEGIN
drop table ##TempCodes
END
EXECUTE sp_executesql #Sql1
Select * from ##TempCodes

Stored procedure couldn't execute the entire statement in sybase

I have created a stored procedure in Sybase using interactive sql which compares two rows from two tables with same structure and if there is any difference in any column's data of the table then it returns that particular row.
Stored procedure is written as below:
CREATE or replace PROCEDURE Validation
#databaseTo SYSNAME,
#tableTo SYSNAME,
#tableFrom SYSNAME
AS
BEGIN
DECLARE #stmt NVARCHAR(10000)
DECLARE #columnName VARCHAR(100)
DECLARE #nameList VARCHAR(8000)
select #nameList=""
select #stmt=""
select #columnName=""
SET NOCOUNT ON
DECLARE c1 cursor
for select name
from syscolumns
where id=(select id
from sysobjects
where name=#tableFrom)
OPEN c1
FETCH c1
INTO #columnName
while( ##sqlstatus!=2)
BEGIN
if(#columnName!= "rqst_id")
BEGIN
select #nameList=#nameList+"a."+#columnName+"= b."+#columnName+" AND "
END
FETCH c1
INTO #columnName
END
close c1
select #nameList=#nameList+"a.rqst_id=b.rqst_id"
PRINT #nameList
PRINT #tableFrom
select #stmt='select a.* from '+ #tableFrom+' a LEFT JOIN '+ #databaseTo+'.dbo.'+#tableTo+' b on '+ #nameList+' where b.rqst_id IS NULL'
PRINT #stmt
EXEC #stmt
END
this stored procedure compiles properly but when executed using below statement
EXEC dbo.Validation ('fr2015_dev','fr300output_cost','fr300output_cost')
I get this error
"Couldn't execute statement
Stored procedure 'select a.* from fr300output_cost a LEFT JOIN fr2015_dev.dbo.fr300output_cost b on a.carrier_id= b.carrier_id AND
a.rec_num= b.rec_num AND a.amenity_cost= b.amenity_cost AND
a.circuity_cost= b.circuity_cost AND a.lost_utilization_cost=
b.lost_utilization_cost AND a.dest_fuel_cost= b.dest_fuel_cost AND
a.future_stop_cost= b.future_stop_cost AND a.s' not found.
...
sp_help may produce lots of outputs.
sybase error code 2812"
I see this proc on running 'sp_help'.Please help me solving this problem .
This way
EXEC #stmt
you run a procedure so this the reason for your error.
For run dynamic sql you have to use parenthesis as below
EXEC (#stmt)
your full code should be
CREATE or replace PROCEDURE Validation
#databaseTo SYSNAME,
#tableTo SYSNAME,
#tableFrom SYSNAME
AS
BEGIN
DECLARE #stmt NVARCHAR(10000)
DECLARE #columnName VARCHAR(100)
DECLARE #nameList VARCHAR(8000)
select #nameList=""
select #stmt=""
select #columnName=""
SET NOCOUNT ON
DECLARE c1 cursor
for select name
from syscolumns
where id=(select id
from sysobjects
where name=#tableFrom)
OPEN c1
FETCH c1
INTO #columnName
while( ##sqlstatus!=2)
BEGIN
if(#columnName!= "rqst_id")
BEGIN
select #nameList=#nameList+"a."+#columnName+"= b."+#columnName+" AND "
END
FETCH c1
INTO #columnName
END
close c1
select #nameList=#nameList+"a.rqst_id=b.rqst_id"
PRINT #nameList
PRINT #tableFrom
select #stmt='select a.* from '+ #tableFrom+' a LEFT JOIN '+ #databaseTo+'.dbo.'+#tableTo+' b on '+ #nameList+' where b.rqst_id IS NULL'
PRINT #stmt
EXEC (#stmt)
END

Stored Procedure and populating a Temp table from a linked Stored Procedure with parameters

I have a Stored Procedure (SP) in which I pass in one value. In this SP, I am trying to create/populate a Temp Table from the result of another SP that is on a Linked/remote server. That is I am trying to executute an SP in my SP and populate a temp table which my query will use.
I have tried using the following syntax, but it does not work as it seems openquery does not like the "+" or the #param1 parameter.
select * into #tempTable
from openquery([the Linked server],'exec thelinkedSPname ' + #param1)
If I have the parameter value hard coded in this it works fine.
select * into #tempTable
from openquery([the Linked server],'exec thelinkedSPname 2011')
I have also gone as far as manually building the temp table and trying to execute the linked SP but that does not work as well.
create table #tempTable(
.
.
.
)
insert into #tempTable
(
.
.
.
)
Exec [the Linked server],'exec thelinkedSPname ' + #param1
Any suggestions as to how to populate a temp table from within a SP that executes a SP via a linked server. Note the above SQL is only pseudo code
I think you are gonna need dynamic SQL, since you can't pass the parameter to an OPENQUERY like that (but first visit this link) So you would have something like this:
create table #tempTable(
.
)
DECLARE #param1 VARCHAR(10), #Query VARCHAR(8000)
SET #param1 = '2011'
SET #Query = '
SELECT *
FROM OPENQUERY([Linked Server],''exec thelinkedSPname '' + #param1+''')'
INSERT INTO #tempTable
EXEC(#Query)
With the usual disclaimers about guarding dynamic SQL, you can do this without OPENQUERY etc. Just call sp_executesql remotely:
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'EXEC thelinkedSPname ' + #param1 + ';';
INSERT #temptable EXEC [LinkedServerName].database.dbo.sp_executesql #sql;
I use this method quite frequently:
DECLARE #YEAR AS VARCHAR(4) SET #YEAR = 2015
DECLARE #SQL AS VARCHAR(MAX)
DECLARE #OPENQUERY AS VARCHAR(MAX)
DECLARE #LINKEDSERVER AS VARCHAR(MAX) SET #LINKEDSERVER = 'Name of Linked Server here with out brackets'
SET #SQL='
Select
tbl1.*
FROM
dbo.Table_ON_LINKED_SERVER AS tbl1
WHERE
tbl1.number_id = ''''1''''
AND YEAR(tbl1.DATETIME) = ' + #YEAR + '
AND tbl1.NAME <> ''''%JONES%''''
'''
SET #OPENQUERY = 'SELECT * INTO ##GLOBAL_TEMP_NAME FROM OPENQUERY(['+ #LINKEDSERVER +'],''' + #SQL + ')'
--SELECT #OPENQUERY
EXEC(#OPENQUERY)
Two words: Dynamic Query.
Try this:
DECLARE #TSQL varchar(8000)
SELECT #TSQL = 'SELECT * INTO #tempTable FROM OPENQUERY([the Linked server],''exec [the Linked server].DBName.dbo.thelinkedSPname ' + #param1 + ''')'
EXEC (#TSQL)
This is well documented here:
How to pass a variable to a linked server query
With some care you could use a shared temp table:
DECLARE #Qry AS VARCHAR(MAX)
SET #Qry = 'select * into ##tempTable from openquery([the Linked server],''exec thelinkedSPname ' + #param1 + ''')'
EXEC (#Qry)
-- Now just use the shared Temp table, or I suppose you could copy it to a temp table just as you wanted it:
SELECT * INTO #tempTable FROM( SELECT * FROM ##tempTable)tbl
DROP TABLE ##tempTable

TSQL dynamic adding of columns in stored procedure

Hi I am writing a large stored procedure, which creates a dynamic report table, of n columns in size, the first 6 are constant the remainder depend on a few arguments passed to the procedure to create the table with the required columns.
The problem that I am having is with the following TSQL
DECLARE #columnname VARCHAR(50)
SET #columnname = 'on_' + #description
IF NOT EXISTS(SELECT * FROM syscolumns WHERE id = OBJECT_ID('reports')
AND NAME = #columnname)
BEGIN
ALTER TABLE reports ADD #columnname VARCHAR(50) NULL
END
I am getting syntax errors with this at the #columnname in the ALTER TABLE statement of the above code.
Also as I am new to this, I am not sure if this is the best way to do this, or if there are better ways in TSQL to generate the required dynamic table.
Try this:
declare #sql nvarchar(100)
set #sql = 'ALTER TABLE reports ADD '+ #columnname+' VARCHAR(50) NULL'
exec sp_executesql #sql
Try
DECLARE #columnname VARCHAR(50)
SET #columnname = '[on_' + #description +']'
IF NOT EXISTS(SELECT * FROM syscolumns WHERE id = OBJECT_ID('reports')
AND NAME = #columnname)
BEGIN
ALTER TABLE reports ADD #columnname VARCHAR(50) NULL
END
Cannot get around having to do it dynamically I believe so change your BEGIN block to something like this:
DECLARE #sql VARCHAR(8000)
BEGIN
SET #sql = 'ALTER TABLE Table_1 ADD '+#columnname+' VARCHAR(50) NULL'
EXEC(#sql)
END

Resources