I am creating an Execute SQL task in SSIS 2016 which calls an insert stored procedure. I am trying to return the id of the newly created row in the output parameter but facing the following error.
No result rowset is associated with the execution of this query
I had set the SQL Server Profiler on to see what was generated and it was as follows
declare #p4 int
set #p4=NULL
exec sp_executesql N'Exec [dbo].[InsertPkgAudit] #P1,#P2',N'#P1 varchar(16),#P2 int OUTPUT','CoreReferenceETL',#p4 output
select #p4
If I execute the following it manually it works
DECLARE #auditId INT;
EXEC [dbo].[InsertPkgAudit] #packageName = 'CoreReferenceETL', #auditId = #auditId OUTPUT;
PRINT #auditId;
So it is clear that the stored procedure is fine but some problem with the way its called in SSIS. Could somebody help ?
The Execute SQL task contains the following statement
Exec [dbo].[InsertPkgAudit] #packageName =?, #auditId = ?
The parameter mapping is as follows
The result pane is as follows
The stored procedure is as follows:
CREATE Procedure [dbo].[InsertPkgAudit]
#packageName varchar(100),
#auditId int output
AS
BEGIN
SET NOCOUNT ON
INSERT INTO [dbo].[PkgAudit] ([PackageName], [StartTime])
VALUES (#packageName, GETDATE());
SET #auditId = SCOPE_IDENTITY();
END
The table structure is as follows
You have told SSIS that your procedure returns a result set. But it doesn't. It populates an OUTPUT parameter instead.
You can either change your proc to return a resultset, or you can modify the Execute task and
Specify No Result Set
Change the query to this:
`Exec [dbo].[InsertPkgAudit] #packageName =?, #auditId = ? OUTPUT`
I just had a similar issue and while looking for some sort of solution I came across this old post. I wasn't able to find the solution online but, here is how I resolved my issue. I hope this helps folks in the future.
If you really need to get the data passed via RowSet, you will need to select as
'ColumnName'.
Declare #fname varchar(50)
Declare #lname varchar(50)
set #fname ='John'
set #lname= 'Doe'
select #fname, #lname--without column name
select #fname as 'firstName', #lname as 'LastName'--with column name
Here is how they would show up in the results.
You can now map the result to proper variable.
Related
As described in title, I am trying to systematically get stored procedure pararameter names and their corresponding values inside the execution of the proper stored procedure.
First point, which is taking stored procedure parameter names, is easy using table [sys].[all_parameters] and the stored procedure name. However, getting the actual values of these parameters is the difficult part, specially when you are not allowed to use table [sys].[dm_exec_input_buffer] (as a developer, I am not allowed to read this table, since it is a system administrator table).
Here is the code I have so far, which I am sure can serve you as a template:
CREATE PROCEDURE [dbo].[get_proc_params_demo]
(
#number1 int,
#string1 varchar(50),
#calendar datetime,
#number2 int,
#string2 nvarchar(max)
)
AS
BEGIN
DECLARE #sql NVARCHAR(MAX);
DECLARE #ParameterNames NVARCHAR(MAX) = ( SELECT STRING_AGG([Name], ',') FROM [sys].[all_parameters] WHERE OBJECT_ID = OBJECT_ID('[dbo].[get_proc_params_demo]') )
SET #sql = N'SELECT ' + #ParameterNames;
DECLARE GetParameterValues CURSOR FOR
SELECT DISTINCT [Name] FROM [sys].[all_parameters] WHERE OBJECT_ID = OBJECT_ID('[dbo].[get_proc_params_demo]');
OPEN GetParameterValues;
DECLARE #param_values NVARCHAR(MAX) = NULL
DECLARE #StoredProcedureParameter NVARCHAR(MAX)
FETCH NEXT FROM GetParameterValues INTO #StoredProcedureParameter;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #param_values = 'ISNULL('+#param_values+','')'+#StoredProcedureParameter+','
EXEC(#param_values)
FETCH NEXT FROM GetParameterValues INTO #StoredProcedureParameter;
END;
CLOSE GetParameterValues;
DEALLOCATE GetParameterValues;
SET #param_values = LEFT(#param_values, LEN(#param_values) - 1)
EXEC sp_executesql #sql,#ParameterNames,#param_values;
END
EXEC [dbo].[get_proc_params_demo]
#number1=42,
#string1='is the answer',
#calendar='2019-06-19',
#number2=123456789,
#string2='another string'
This is my approach trying to dynamically get parameter actual values inside a cursor, but it does not work, and I am clueless so far. I know it is quite rudimentary, and I am happy to hear other approaches. To be fair, I don't know if this problem is even possible to solve without system tables, but it would be great.
EDIT: This is an attempt to get a generic code that works on any stored procedure. You do not want to hardcode any parameter name. The only input you have is the stored procedure name via OBJECT_NAME(##PROCID)
I am trying to call a stored procedure from an automation script in Maximo.
The stored procedure is being called correctly and is running from the script fine,
the problem I am running into is when it returns the output value it is setting it
as None when it should be a string.
I have tested the stored procedure in SQL Server and I am getting the correct string I want when I call the procedure.
My automation script call looks like this:
storedProcedureWithParameter = '{call dbo.insertdelbkp3(?,?,?)}';
callableStatement = dbConnection.prepareCall(storedProcedureWithParameter);
callableStatement.setString(1, pMon);
callableStatement.setString(2, ArchData);
callableStatement.registerOutParameter(3, Types.VARCHAR);
callableStatement.execute();
output = str(callableStatement.getString(3));
print(output)
Does anyone have a thought on what is going wrong? Thanks.
EDIT******
For more information my stored procedure is archiving old records and should return a string when done. When I call my procedure in this script the records are getting archived but it is not returning my string. If I call the stored procedure inside SQL it archives records and returns the string as it should.
EDIT2******
The automation script is in Maximo being triggered by a cron task if that provides any more insight
EDIT3******
This is the stored procedure I am calling from my script. The stored procedure it calls(dbo.insertintobkp3) is fully functional and working fine.
USE [maxsb76]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[insertdelbkp3]
#mOld varchar(10), #TabList varchar(500), #logMessage VARCHAR(MAX) OUTPUT
as
DECLARE #sp varchar(500),#tp varchar(20)
BEGIN
DECLARE #oldRecToArch VARCHAR(MAX), --inserts into woarchrecords that are ready for arch
#rowcount int, --count for how many values are inserted into WOARCHRECORDS
#inDelMessage VARCHAR(MAX)
SET #sp=#TabList
SET #logMessage = 'List of backup tables are : '+#sp+'\n'
print 'List of backup tables are : '+#sp
if(((Select CAST(#mOld AS INT)) < 60) or (#mOld=NULL))
SET #mOld='60'
--inserts records to be archived into woarchrecords
SET #oldRecToArch = 'insert into dbo.woarchrecords(wonum, siteid) select wonum, siteid from dbo.workorder where status in (''CAN'', ''CLOSE'') and statusdate < dateadd(year,-'+#mOld+'/12,getdate())'
execute(#oldRecToArch)
SELECT #rowcount = ##ROWCOUNT
SET #logMessage = #logMessage + Convert(Varchar(12),#rowCount) +' new archivable records inserted into WOARCHRECORDS \n'
print Convert(Varchar(12),#rowCount) +' new archivable records inserted into WOARCHRECORDS'
DECLARE spcur cursor for select value from string_split(#sp,',')
OPEN spcur
FETCH next from spcur into #tp
WHILE 1=1
BEGIN
--checks that we were given tables to alter then seperates them and passes each table to be updated
IF ##FETCH_STATUS=0
BEGIN
SET #logMessage = #logMessage + 'Currently Archiving Table '+SUBSTRING(#tp,1,LEN(#tp)-3)+'\n'
print 'Currently Archiving Table '+SUBSTRING(#tp,1,LEN(#tp)-3)
if((SELECT TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='dbo' AND TABLE_NAME=#tp) is not null)
exec dbo.insertintobkp3 #mOld=#mOld,#TabList=#tp,#insertDeleteMessage=#inDelMessage output
SET #logMessage = #logMessage + #inDelMessage
FETCH next from spcur into #tp
END
IF ##FETCH_STATUS=-1
BREAK
END
print #logMessage
CLOSE spcur
DEALLOCATE spcur
END
Hi guys thanks for the comments and help. I figured out the SetString function for the ArchData was not passing my full list of tables. I instead fetched tables from the stored procedure and it is now working.
I have edited my SQL code blocks to more accurately show what is going on
Say I have a simple stored procedure:
CREATE PROCEDURE [DBO].[FOO]
(#VARIABLE VARCHAR(500))
AS
BEGIN
SELECT AVG(BAR)
FROM MYTABLE
WHERE THING = #VARIABLE AND RTRIM(LTRIM(THING)) <> ''
END
When I call this stored procedure from my classic ASP page; which in this case would be with:
Set foo = Server.CreateObject("ADODB.RecordSet")
curCmd = "Foo 'MYVARIABLE'"
foo.Open curCmd, connectionString
I get this error (on the same line as the page opens the foo object):
Arithmetic overflow error converting varchar to data type numeric.
If I call the stored procedure manually in the terminal (IDE?); then it works fine.
Also if I recreate the stored procedure as the following:
CREATE PROCEDURE [DBO].[FOO]
(#VARIABLE VARCHAR(500))
AS
BEGIN
DECLARE #VARIABLE2 VARCHAR(500) = #VARIABLE
SELECT AVG(BAR)
FROM MYTABLE
WHERE THING = #VARIABLE2 AND RTRIM(LTRIM(THING)) <> ''
END
Then the stored procedure runs fine.
I have tried dropping and recreating the stored procedure (without using the re-declaration trick), but it does not fix the issue.
*As an aside; there is validation on the data being inserted into the table to ensure that only numbers (integers) are being entered for the THING field. The THING field can also be blank; hence the where clause.
I basically have two questions:
Why does re-declaring the same variable type with the same data fix the issue?
Is there a way I can fix my problem without using this silly "re-declaration" trick?
Thanks in advance for any help with this.
I think you can get the same error if you use begin/end:
CREATE PROCEDURE [DBO].[FOO] (
#VARIABLE VARCHAR(500)
)
AS
BEGIN
DECLARE #VARIABLE2 VARCHAR(500) = #VARIABLE;
SELECT AVG(BAR) FROM MYTABLE WHERE THING = #VARIABLE2;
END;
Then, both statements will be part of the stored procedure body and you can work on fixing the data so it will work.
Due to the constraints within the workplace I have to use a local stored procedure to call another remote stored proc on a linked sql server, however the problem lies in passing a necessary parameter to the remote stored proc.
This is the query I constructed:
select *
from OPENQUERY([REMOTE_SRVR],'exec db.dbo.dwStoredProc_sp ''#id''')
In order to pass #id to the remote stored proc I understand I could concatenate the above as a string and then use exec
Something along the lines of:
set #query = 'select * from OPENQUERY([REMOTE_SRVR], ''EXEC db.dbo.dwStoredProc_sp '' #id '''''
exec(#query)
I cannot get the local stored proc to successfully call the other. The single quote mess doesn't help!
I get the error: Could not find stored procedure 's'
To help with the quote mess I like to do this in steps. It is more code but easier to understand. I am not sure from your example if #id is an integer. In that case you can lose the double quotes around __ID__.
set #query = 'EXEC db.dbo.dwStoredProc_sp ''__ID__'''
set #query = REPLACE(#query,'__ID__',#id)
set #query = REPLACE(#query,'''','''''')
set #query = REPLACE('SELECT * FROM OPENQUERY([REMOTE_SRVR], ''__REMOTEQUERY__'')','__REMOTEQUERY__',#query)
You could avoid dynamic queries by simply by using EXEC (..., ParamValue) AT LinkedServer (see product's documentation, example [L. Using a parameter with EXECUTE and AT linked_server_name]):
1) On target server:
CREATE PROCEDURE dbo.Proc1( #id NVARCHAR(50) )
AS
SELECT #id AS [id];
GO
2) On the source server you create the linked server and then you can call the stored procedure using EXEC ... AT ... syntax:
DECLARE #p1 NVARCHAR(50);
SET #p1 = N'DROP TABLE dbo.CocoJambo'
EXECUTE (N'dbo.Proc1 ? ' , #p1 ) AT LOCALINKEDSEREV
Output:
id
------------------------
DROP TABLE dbo.CocoJambo
I'm making this stored procedure call:
exec sp_executesql N'EXEC MyStoredProcedure
#MyId = #0, #MyVarField = #1',
N'#0 int, #1 nvarchar(4000)',
#0=2, #1='lll/kkk'
The stored procedure is just a simple select, looking for MyVarField = 'lll/kkk', but the / in the parameter seems to break it... it can't find the db row anyway.
If I pass in 'ffflll' then it finds the row which contains lllkkk, just doesn't find it when there's a / in it. What's that about?
ALTER PROCEDURE [dbo].[MyStoredProcedure]
#MyId int,
#MyVarField varchar
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM MyTable WHERE VarField = #VarField
END
What do I need to do to the stored procedure to make it accept the / as part of a varchar?
Try making your parameter match the same type as the statement (and presumably the underlying column), and giving it a length:
ALTER PROCEDURE [dbo].[MyStoredProcedure]
#MyId int,
#MyVarField NVARCHAR(4000)
AS
...
I don't think the failure currently has anything to do with the slash. Try this:
CREATE PROCEDURE dbo.foo
#bar VARCHAR
AS
PRINT #bar;
GO
EXEC dbo.foo '12345';
For some background, please read:
Bad habits to kick : declaring VARCHAR without (length)
Forward slash (“/” ) is the shortcut for RUN command (like “go” in mysql or sqlserver).
http://power2build.wordpress.com/2011/12/09/forward-slash-in-sqlplus/