Select data from another database in storedprocedure - sql-server

I try to select data from a table of another database in my storedprocedure and the name of the other database is given by parameter. I get an error message:
'Invalid object name [#DbName].dbo.Setup'.
CREATE PROCEDURE [dbo].[spUndeliverableOrders]
#DbName sysname
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Sortfield nvarchar(50)
SET #Sortfield = (SELECT COALESCE(Text, 'ToDoListeDatum') AS SortField FROM [#DbName].dbo.Setup WHERE label like 'ComboBoxSetupBatchReihenfolge')
END
GO
Can someone help me to solve this problem?

Like #ThomasSchremser said:
DECLARE #sqlquery varchar(1000)
SET #sqlquery = '(SELECT COALESCE(Text, ''ToDoListeDatum'') AS SortField FROM ['+#DbName+'].dbo.Setup WHERE label like ''ComboBoxSetupBatchReihenfolge'')'
It is upto you to decide weither you what to populate a table/variable with the results.
Either use:
insert into #table(column) exec #sqlquery...
or
sp_executesql #sqlquery...

You need to use dynamic query as below
CREATE PROCEDURE [dbo].[spUndeliverableOrders]
#DbName sysname
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #Str varchar(max)
CREATE TABLE #Result(Res VARCHAR(MAX))
SET #Str = 'insert into #Result SELECT TOP 1 COALESCE(Text, ''ToDoListeDatum'') AS SortField FROM ['+#DbName+'].dbo.Setup WHERE label like ''ComboBoxSetupBatchReihenfolge'''
exec(#str)
select Res from #Result
END

Modified per your script:
DECLARE #Str varchar(max)
CREATE TABLE #Result(Res VARCHAR(MAX))
SET #Str = ' SELECT TOP 1 COALESCE(Text, ''ToDoListeDatum'') AS SortField FROM ['+#DbName+'].dbo.Setup WHERE label like ''ComboBoxSetupBatchReihenfolge'''
insert into #Result
EXEC(#Str)

Related

Have anyone a solution to send row parameter to a stored prodedure in MS-SQL Server with dynamic Column Arrangement?

I Could write a trigger for a table that is able to detect updated columns and logs the changes. I want to make a stored procedure from this trigger and call it when required. But I do not know how can I send "inserted" or "updated" rows that are valid in trigger body, to this SP.
Here is my trigger :
CREATE TRIGGER [dbo].[tgr_MyTable_TransactionLogUpdate]
ON [dbo].[MyTable]
AFTER UPDATE
AS
BEGIN
if (select F_SharhRadif from [Payeh.Decode] where F_ShJadval=18 and F_ShRadif=1)='2'
begin
return
end
declare #userid int=(select top 1 userid from inserted)
declare #computername nvarchar(50)=(select top 1 computername from inserted)
declare #ip nvarchar(50)=(select top 1 IP from inserted)
declare #zamantaqeer datetime=(select top 1 F_ZamanTaqeer from inserted)
declare #changetime =GETDATE()
DECLARE #tableID BIGINT=(SELECT id FROM sys.sysobjects WHERE [name]='MyTable')
DECLARE #ColCount INT=(SELECT COUNT(*) FROM sys.syscolumns WHERE id=#tableID)
DECLARE #ColIndex INT=1
DECLARE #UpdateDetails NVARCHAR(MAX)=''
DECLARE #ColName NVARCHAR(1000)
DECLARE #ByteIndex INT
SELECT * INTO #d FROM deleted
SELECT * INTO #i FROM inserted
WHILE (#ColIndex<=#ColCount)
BEGIN
--IF (COLUMNS_UPDATED()&POWER(2,#ColIndex-1) <> 0)
SET #ByteIndex=((#ColIndex-1)/8)+1
IF (CONVERT(INT,SUBSTRING(COLUMNS_UPDATED(),#ByteIndex,1))&POWER(2,((#ColIndex-1)%8)) <> 0)
BEGIN
SET #ColName=(SELECT [name] FROM sys.syscolumns WHERE id=#tableID AND colid=#ColIndex)
DECLARE #OldValue NVARCHAR(MAX)
DECLARE #NewValue NVARCHAR(MAX)
DECLARE #ParmDefinition NVARCHAR(100)=N'#DeletedValue NVARCHAR(MAX) OUTPUT'
DECLARE #SQL NVARCHAR(1000)='SELECT #DeletedValue=LTRIM(RTRIM(CONVERT(nvarchar(MAX),'+#ColName+'))) FROM #d'
EXEC sp_executesql #SQL,#ParmDefinition,#DeletedValue=#OldValue OUTPUT
SET #ParmDefinition = N'#InsertedValue NVARCHAR(MAX) OUTPUT'
SET #SQL= 'SELECT #InsertedValue=LTRIM(RTRIM(CONVERT(nvarchar(MAX),'+#ColName+'))) FROM #i'
EXEC sp_executesql #SQL,#ParmDefinition,#InsertedValue=#NewValue OUTPUT
IF (#OldValue<>#NewValue)
BEGIN
SET #UpdateDetails=#UpdateDetails+#ColName+': OLD="'+ #OldValue+'" -New="'+#NewValue+'", '
END
END
SET #ColIndex=#ColIndex+1
END
IF (LEN(#UpdateDetails)>0)
BEGIN
SET #UpdateDetails=SUBSTRING(#UpdateDetails,1,LEN(#UpdateDetails)-1)
END
ELSE
BEGIN
SET #UpdateDetails='No Changes'
END
--[User.TransactionLog] is the name of the table that stores the history of changes
INSERT INTO [User.TransactionLog]
([Tablename],[OperationType],[Desciption],[UserID],[ComputerName],[IP],[ChangeTime])
SELECT 'MyTable',2,#UpdateDetails,'',#userid,#computername,#ip, #changetime
DROP TABLE #d
DROP TABLE #i

Pass current dbName and execute procedure

See this...
SELECT *
INTO #WL_Klijenti
FROM OPENROWSET ('SQLOLEDB','Server=(local);TRUSTED_CONNECTION=YES;','SET
FMTONLY OFF; SET NOCOUNT ON; EXEC
WBANKA_KBBL2.dbo.sp_kbbl_WachLista_Priprema ''2017.09.30'', ''2017.09.30'',
0')
AS tbl
The part : EXEC WBANKA_KBBL2 should be replaced with the current db used, so that the user does not have to specify it manualy.
I had an idea of a procedure with an output parameter which will return current database and store it in a variable and this was my try:
SP Looks like this:
CREATE procedure dbo.getCurrentDB
(
#dbName varchar(30) OUTPUT
)
AS
BEGIN
set #dbName = (select db_name())
--select #dbName
END
go
How can I pass my current db used to the procedure call, instead of specifying it manually?
EDIT:
When I run it like this I receive A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations
declare #dbName varchar(30)
exec getCurrentDB #dbName output
DECLARE #ORS varchar(MAX);
SELECT #ORS = 'Server=(local);TRUSTED_CONNECTION=YES;','SET
FMTONLY OFF; SET NOCOUNT ON; exec
select ' + QUOTENAME([name] + '.dbo.sp_kbbl_WachLista_Priprema
''2017.09.30'', ''2017.09.30'',
0')
FROM sys.databases
WHERE [name] = #dbName
SELECT *
INTO #WL_Klijenti
FROM OPENROWSET ('SQLOLEDB',#ORS)
AS tbl;

How to use variable as table name in select into statement?

I have a problem with treating table name as variable as I need to put the results to different table each month automatically (without using any advanced procedures to make this query dynamic). Can somebody help me to modify this code and make it work?
declare #exp_dte as date;
set #exp_dte='2015-12-31';
print (#exp_dte);
declare #tab_mth as nvarchar(max);
set #tab_mth=year(#exp_dte)*100+month(#exp_dte);
print (#tab_mth);
declare #tab_name as nvarchar(max)
set #tab_name='mis_anl.dbo.BIK_' + #tab_mth
print (#tab_name);
IF OBJECT_ID (N'#tab_name', N'U') IS NOT NULL
begin
drop table #tab_name
end
select distinct
*
into #tab_name
from table_x
You have to use dynamic SQL to set name at runtime:
DECLARE #exp_dte DATE = '2015-12-31';
DECLARE #tab_name SYSNAME = '[dbo].' + QUOTENAME('BIK_' + FORMAT(#exp_dte, 'yyyyMM'));
IF OBJECT_ID (#tab_name, N'U') IS NOT NULL
BEGIN
EXEC('DROP TABLE' + #tab_name);
END
DECLARE #sql NVARCHAR(MAX) = N'SELECT DISTINCT *
INTO #tab_name
FROM table_x';
SET #sql = REPLACE(#sql, '#tab_name', #tab_name);
EXEC [dbo].[sp_executesql] #sql;
LiveDemo
Remarks:
Try to be more conscise
You could use FORMAT to get yyyyMM (SQL Server 2012+)
Always QUOTENAME generated identifiers to avoid SQL Injection attacks
I strongly recommend to read The Curse and Blessings of Dynamic SQL especially CREATE TABLE #tbl.
use dynamic sql ,you cant user table names as variables
declare #exp_dte as date;
set #exp_dte='2015-12-31';
declare #tab_mth as nvarchar(max);
set #tab_mth=year(#exp_dte)*100+month(#exp_dte);
declare #tab_name as nvarchar(max)
set #tab_name='mis_anl.dbo.BIK_' + #tab_mth
declare #sql1 nvarchar(max)
set #sql1='drop table '+#tab_name;
IF exists(select 1 from information_schema.tables where table_name=#tab_name)
begin
exec(#sql1);
end
declare #sql nvarchar(max)
set #sql='
select distinct
*
into '+#tab_name+'
from table_x'
exec (#sql)

Use sql variable as where clause in sql

i want to do this:
DECLARE #str varchar(max)
DECLARE #cnt bigint
set #str= 'where column=value'
set #cnt= (select count(*) from user+#str)
but the where clause is not working. getting no error but it will just ignore the where condition.
I previously suggested wrapping your last line in EXEC(), but you can't do this and return results to a variable. To do that, use the following in place of your last line:
create table #temp (theCount int)
insert into #temp EXEC('select count(*) from Photos '+#str)
set #cnt= (select top 1 theCount from #temp)
drop table #temp
Check below code, in your case condition is dynamic so you need to dynamic sql.
DECLARE #sSQL nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
DECLARE #str nvarchar(500);
set #str= 'where column=value'
SELECT #sSQL = N'SELECT #retvalOUT = COUNT(*) FROM user '+ #str +' ' ;
SET #ParmDefinition = N'#retvalOUT int OUTPUT';
EXEC sp_executesql #sSQL, #ParmDefinition, #retvalOUT=#retval OUTPUT;
SELECT #retval;
use the execute sql syntax http://technet.microsoft.com/en-us/library/ms188001.aspx
Hope this will solve your problem

How to use the result from a procedure in another procedure in SqlServer?

I'm trying to combine a result mixed with some SELECTs.
I wanted to set #result combined with the result of [proc_Get_Frame_CourseNum] procedure but It didn't work.
declare #str varchar(300)
declare #result varchar(200)
declare #temp varchar(20)
declare #i int
set #str='110,120,130,140'
set #result=''
set #temp=''
set #i=0
while #i<len(#str)/4+1
begin
set #temp=substring(#str,1,3)
set #str=substring(#str,2,len(#str))
set #result=#result+ exec [proc_Get_Frame_CourseNum] #temp
set #i=#i+1
end
select #temp
Personally, I'd make use of output variables
CREATE PROCEDURE proc_Get_Frame_CourseNum
#temp varchar(20),
#outValue varchar(50) OUTPUT
AS
BEGIN
--do stuff
--before you leave the method or do your final SELECT
SET #outValue = 'whatever your result is'
--more stuff
END
Then in your code, you just go:
DECLARE #outValue VARCHAR(20)
-- rest of your code
EXEC [proc_Get_Frame_CourseNum] #temp, #outValue OUT
SET #result = #result + #outValue
Alternatively, you could just dump the results of the SP into a temp table, then read from it into your #Result variable.
You can't interpolate the result of one procedure by appending it.
I am assuming now that [proc_Get_Frame_CourseNum] returns a scalar result.
So run exec [proc_Get_Frame_CourseNum] #temp in another line of batch (before set #result = #result + call)
Your query should look like,
declare #scalarResult = exec [proc_Get_Frame_CourseNum] #temp
set #result=#result+ #scalarResult

Resources