SQL - Return Output To Stored Procedure - sql-server

I have a stored procedure I have created so that I can enter lines into a table and subsequently return the INSERTED.ID so I can return this ID to the SQL Command that sent it to input the ID into that table.
I have used OUTPUT INSTEAD.ID before and this works fine when I do it as just an insert statement but how do I get the same result with a Stored Procedure.
I have done the following but can't seem to get it to output correctly.
CREATE PROCEDURE sp_XStream_Send
-- Add the parameters for the stored procedure here
#Dept VARCHAR(30),
#Process VARCHAR,
#RequestDT DATETIME,
#RequestType VARCHAR,
#RequestBranch INT,
#RequestPolRef VARCHAR,
#RequestXML VARCHAR,
#ReturnID INT OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #OutputTbl TABLE (ID INT)
INSERT INTO dbo.XStream_Log
( Department ,
Process ,
RequestDT ,
RequestType ,
RequestBranch ,
RequestPolicyRef ,
RequestXML
)
OUTPUT INSERTED.ID INTO #OutputTbl(ID)
VALUES ( #Dept,
#Process,
#RequestDT,
#RequestType,
#RequestBranch,
#RequestPolRef,
#RequestXML
)
SELECT #ReturnID = ID FROM #OutputTbl
RETURN
END
GO
When i do the EXEC it wants me to send the #ReturnID but I don't want to Input anything into it, I want the output of the inserted ID.
Any help, cheers.
UPDATE
I am executing my stored procedure like so:
DECLARE #ID INT;
EXEC dbo.sp_XStream_Send #Dept = 'IT', -- varchar(1)
#Process = 'XStream Test', -- varchar(1)
#RequestDT = '2016-05-09 09:28:38', -- datetime
#RequestType = 'create-broomsrisk', -- varchar(1)
#RequestBranch = 0, -- int
#RequestPolRef = 'POMS01PC01', -- varchar(1)
#RequestXML = '<TestXML></TestXML>', -- varchar(1)
#ReturnID = #ID OUTPUT;
I am just getting 'Command(s) completed successfully' and not the actual ID.

Related

SQL Server SCOPE_IDENTITY does not run linked server

I have two servers that are connected using a linked server. When I run this procedure, it inserts a record one to other and that time I want ID from my second server - how do this?
Alter PROCEDURE [dbo].[stp_TransferJob]
(
#JOB_id AS bigint,
#PartyId as int,
#Commission as decimal(18,2),
#myid as varchar(max),
#ident_out as bigint output
)
AS
BEGIN
INSERT INTO [111.163.103.122].Taxi.dbo.booking (FromLocTypeId,ToLocTypeId,FromLocId,ToLocId,VehicleTypeId,DriverId,ReturnDriverId,CustomerId,CustomerName,CustomerEmail,CustomerPhoneNo,CustomerMobileNo,JourneyTypeId,BookingNo,BookingDate,NoofPassengers,NoofLuggages,NoofHandLuggages,PickupDateTime,ReturnPickupDateTime,IsCompanyWise,CompanyId,FareRate,PaymentTypeId,SpecialRequirements,FromAddress,ToAddress,FromPostCode,ToPostCode,FromDoorNo,ToDoorNo,FromStreet,ToStreet,FromFlightNo,FromComing,BookingStatusId,DistanceString,AutoDespatch,AutoDespatchTime,AddOn,AddBy,AddLog,EditOn,EditBy,EditLog,OrderNo,PupilNo,ParkingCharges,WaitingCharges,ExtraDropCharges,MeetAndGreetCharges,CongtionCharges,TotalCharges,DepartmentId,ReturnFareRate
,ArrivalDateTime,MasterJobId,DisablePassengerSMS,DisableDriverSMS,IsCommissionWise,DriverCommission,DespatchDateTime,JobOfferDateTime,BookingTypeId,DriverCommissionType,IsBidding,IsQuotation,CostCenterId,CashRate,AccountRate,WaitingMins
,ExtraMile,AcceptedDateTime,POBDateTime,STCDateTime,ClearedDateTime,CancelReason,TotalTravelledMiles,CompanyPrice,SubCompanyId,PartyId,
FromOther,ToOther,TransferJobId,TransferJobCommission,BookingTypeId,ViaString)
SELECT
FromLocTypeId,ToLocTypeId,FromLocId,ToLocId,VehicleTypeId,null,ReturnDriverId,CustomerId,CustomerName,CustomerEmail,CustomerPhoneNo,CustomerMobileNo,JourneyTypeId,BookingNo,BookingDate,NoofPassengers,NoofLuggages,NoofHandLuggages,PickupDateTime,ReturnPickupDateTime,IsCompanyWise,null,FareRate,PaymentTypeId,SpecialRequirements,FromAddress,ToAddress,FromPostCode,ToPostCode,FromDoorNo,ToDoorNo,FromStreet,ToStreet,FromFlightNo,FromComing,BookingStatusId,DistanceString,AutoDespatch,AutoDespatchTime,AddOn,AddBy,AddLog,EditOn,EditBy,EditLog,OrderNo,PupilNo,ParkingCharges,WaitingCharges,ExtraDropCharges,MeetAndGreetCharges,CongtionCharges,TotalCharges,DepartmentId,ReturnFareRate
,ArrivalDateTime,MasterJobId,DisablePassengerSMS,DisableDriverSMS,IsCommissionWise,DriverCommission,DespatchDateTime,JobOfferDateTime,BookingTypeId,DriverCommissionType,IsBidding,IsQuotation,CostCenterId,CashRate,AccountRate,WaitingMins
,ExtraMile,AcceptedDateTime,POBDateTime,STCDateTime,ClearedDateTime,CancelReason,TotalTravelledMiles,CompanyPrice,1,#PartyId
,FromOther,ToOther,#JOB_id,#Commission,10,ViaString
FROM Booking
WHERE Id = #JOB_id ;
select SCOPE_IDENTITY()
SET #ident_out = ##IDENTITY
-------------------------------------------------------------------------
INSERT INTO [111.163.103.122].Taxi.dbo.booking_ViaLocations (
BookingId,ViaLocTypeId,ViaLocTypeLabel,ViaLocTypeValue,ViaLocId,ViaLocValue,ViaLocLabel )
SELECT
#ident_out,ViaLocTypeId,ViaLocTypeLabel,ViaLocTypeValue,ViaLocId,ViaLocValue,ViaLocLabel
FROM Booking_ViaLocations
WHERE BookingId = #JOB_id
END
return #ident_out
GO
SCOPE_IDENTITY() AND ##IDENTITY SHOW NULL VALUE HOW TO GET ID please help me
You can return int values using a stored procedure
create PROCEDURE [dbo].[stp_TransferJob]
(
#JOB_id AS bigint,
#PartyId as int,
#Commission as decimal(18,2)
)
AS
BEGIN
INSERT INTO [111.163.103.122].Taxi.dbo.booking (FromLocTypeId,ToLocTypeId,FromLocId,ToLocId,VehicleTypeId,DriverId,ReturnDriverId,CustomerId,CustomerName,CustomerEmail,CustomerPhoneNo,CustomerMobileNo,JourneyTypeId,BookingNo,
FromOther,ToOther,TransferJobId,TransferJobCommission,BookingTypeId,ViaString)
SELECT
FromLocTypeId,ToLocTypeId,FromLocId,ToLocId,VehicleTypeId,null,ReturnDriverId,CustomerId,CustomerName,CustomerEmail,CustomerPhoneNo,CustomerMobileNo,JourneyTypeId,BookingNo,FromOther,ToOther,#JOB_id,#Commission,10,ViaString
FROM Booking
WHERE Id = #JOB_id
RETURN (##IDENTITY)
END
Then when you call your procedure on other server:
DECLARE #ident INT;
EXECUTE #ident = stp_TransferJob (plus other parameters)
Since it is more common to do this with error codes, you might prefer an output parameter:
create PROCEDURE [dbo].[stp_TransferJob]
(
#JOB_id AS bigint,
#PartyId as int,
#Commission as decimal(18,2),
#ident_out as int output
)
AS
BEGIN
INSERT INTO [111.163.103.122].Taxi.dbo.booking (FromLocTypeId,ToLocTypeId,FromLocId,ToLocId,VehicleTypeId,DriverId,ReturnDriverId,CustomerId,CustomerName,CustomerEmail,CustomerPhoneNo,CustomerMobileNo,JourneyTypeId,BookingNo,
FromOther,ToOther,TransferJobId,TransferJobCommission,BookingTypeId,ViaString)
SELECT
FromLocTypeId,ToLocTypeId,FromLocId,ToLocId,VehicleTypeId,null,ReturnDriverId,CustomerId,CustomerName,CustomerEmail,CustomerPhoneNo,CustomerMobileNo,JourneyTypeId,BookingNo,FromOther,ToOther,#JOB_id,#Commission,10,ViaString
FROM Booking
WHERE Id = #JOB_id
SET #ident_out = ##IDENTITY
END
Then when you call the procedure you add a declared parameter with an output keyword. Please see msdn

"String or binary data would be truncated" error while updating but not when inserting new record

I understand that this error comes when we try to insert characters more than the capacity of column.
But what I am not able to understand is a recent output in which I was getting the error when updating in the table but not when a new record was getting inserted in the table with the same parameter size.
Table structrue:
Entity
(
#EntityID int,
#Name varchar(200),
#FullName varchar(50),
#ParentEntityID int,
#ShortDesc varchar(255),
#LongDesc varchar(2000)
)
When I am trying to insert a new row, it simply truncates the parameter who has value more than its size (here #FullName), but when I try to update the same values on an existing record, it simply throws the exception.
Why can't it just truncate here also?
Edit::
Procedure for update.
ALTER PROCEDURE [dbo].[Entity_Update]
#EntityID int,
#Name varchar(200),
#FullName varchar(410),
#ParentEntityID int,
#ShortDesc varchar(255),
#LongDesc varchar(2000)
AS
set nocount on;
update dbo.Entity set
Name = #Name,
FullName = #FullName,
ParentEntityID = #ParentEntityID,
ShortDesc = #ShortDesc,
LongDesc = #LongDesc,
DateUpdated = GETUTCDATE()
where EntityID = #EntityID;
return 0;
INSERT Procedure is :
ALTER PROCEDURE [dbo].[Entity_Insert]
#Name varchar(200),
#FullName varchar(410),
#ParentEntityID int,
#ShortDesc varchar(255),
#LongDesc varchar(2000),
#UserID int,
#EntityID int OUTPUT
AS
set nocount on;
set xact_abort on;
begin tran
insert dbo.Entity (
Name,
FullName,
ParentEntityID,
ShortDesc,
LongDesc,
RecordStatus,
DateUpdated)
values (#Name,
#FullName,
#ParentEntityID,
#ShortDesc,
#LongDesc,
1,
GETUTCDATE());
select #EntityID = SCOPE_IDENTITY();
CREATE TABLE Entity
(
EntityID INT IDENTITY
NOT NULL
PRIMARY KEY ,
Name VARCHAR(200) ,
FullName VARCHAR(50) ,
ParentEntityID INT ,
ShortDesc VARCHAR(255) ,
LongDesc VARCHAR(2000)
);
INSERT [Entity] ( [Name], [FullName], [ParentEntityID], [ShortDesc],
[LongDesc] )
VALUES ( 'Name', 'FullName', 0, 'Short', 'Long' );
UPDATE [Entity]
SET [LongDesc] = 'Here is an updated value'
WHERE [FullName] = 'FullName';
SELECT *
FROM [Entity] AS [e];
UPDATE [Entity]
SET [LongDesc] = LEFT('Yet another update ' + REPLICATE('blah ', 1000),
2000)
WHERE [FullName] = 'FullName';
SELECT *
FROM [Entity] AS [e];
Works perfectly well for me.

jdbc sql error: statement did not return a result set

I have two stored procedures as follows:
create stored procedure p1
as
select * from table1 where datediff(day, table1.[date], getdate())
create stored procedure p2
as
declare #t1 table(
ref varchar(20)
)
insert into #t1 select * from table1 where ref = 'some ref'
declare #t2 table(
fname varchar(20),
lname varchar(20),
email varchar(1000)
)
declare #len int = (select count(ref) from #t1)
while #len > 0
begin
declare #value varchar(20) = (select top 1 ref from #t1)
insert into #t2 select * from table2 where ref = #ref
delete from #t1
where ref = #value
set #len = (select count(ref) from #t1)
end
select * from #t2
Java code
....
String query = "Execute [p2]";
try(CallableStatement cstmt = conn.prepareCall(query);
ResultSet rs = cstmt.executeQuery()){
... some code
}
The table variable #t1 hold select result from a table 'table1'
The variable #len hold the number of rows in #t1
Using #len > 0 as condition in while loop, I want to select records from another table 'table2' the table variable #t2 hold the select records from 'table2'
The delete statement removes value from #t1
#len set to new number of rows in #t1
the last statement return all the records store in #t2
The first procedure works fine, but the second procedure works only in SQL Server.
I get this an error message in my java application
statement did not return a resultset
I want this to return a result set with the select statement I have at the
end of the query.
Please is there a way around this?
Your [p2] stored procedure needs to include SET NOCOUNT ON right at the beginning to suppress the "n rows affected" counts so JDBC doesn't get confused as to what it should put into the ResultSet:
CREATE PROCEDURE p2
AS
SET NOCOUNT ON;
declare #t1 table(
ref varchar(20)
)
-- ... and so on
For more information on SET NOCOUNT see
SET NOCOUNT (Transact-SQL)
For more information on precisely what gets returned from a stored procedure call, see
How to get everything back from a stored procedure using JDBC
use method "execute" instead of "executeQuery".

Insert a row to SQL table

I am writing a store procedure in T-SQL which inserts a row to the table, based on parameters
#UserName ,#CompanyName ,#RestName,#Desc
INSERT INTO Orders(UserId,CompanyId,RestId)
SELECT UserNames.Id,CompanyNames.Id,RestNames.Id FROM UserNames,CompanyNames,RestNames
WHERE
UserNames.Name = #UserName AND
CompanyNames.Name = #CompanyName AND
RestNames.Name = #RestName
Besides the insert to the 3 columns above,I also want to insert the #Desc value.
I tried :
INSERT INTO Orders(UserId,CompanyId,RestId,Desc)
VALUES(
(SELECT UserNames.Id,CompanyNames.Id,RestNames.Id FROM UserNames,CompanyNames,RestNames
WHERE
UserNames.Name = #UserName AND
CompanyNames.Name = #CompanyName AND
RestNames.Name = #RestName),#Desc)
Only one expression can be specified in the select list when the subquery is not introduced with EXISTSt-
It doesn`t work giving the following error:
#UserName ,#CompanyName ,#RestName,#Desc
INSERT INTO Orders(UserId,CompanyId,RestId, Desc_Column)
SELECT UserNames.Id,CompanyNames.Id,RestNames.Id , #Desc --<-- Just SELECT that variable
FROM UserNames,CompanyNames,RestNames -- in your select statement.
WHERE UserNames.Name = #UserName
AND CompanyNames.Name = #CompanyName
AND RestNames.Name = #RestName
Retrieve ID Values Inserted
DECLARE #t TABLE (ID INT); --<-- Declare a table variable
INSERT INTO Orders(UserId,CompanyId,RestId, Desc_Column)
OUTPUT Inserted.ID INTO #t --<-- use OUTPUT, get values from INSERTED Table
SELECT UserNames.Id,CompanyNames.Id,RestNames.Id , #Desc --and insert them into your table variable
FROM UserNames,CompanyNames,RestNames
WHERE UserNames.Name = #UserName
AND CompanyNames.Name = #CompanyName
AND RestNames.Name = #RestName
/*At last just simply select from that table variable to get the inserted IDs*/
SELECT * FROM #t

SQL Server OUTPUT clause

I am a little stuck with why I can not seem to get the 'new identity' of the inserted row with the statement below. SCOPE_IDENTITY() just returns null.
declare #WorkRequestQueueID int
declare #LastException nvarchar(MAX)
set #WorkRequestQueueID = 1
set #LastException = 'test'
set nocount off
DELETE dbo.WorkRequestQueue
OUTPUT
DELETED.MessageEnvelope,
DELETED.Attempts,
#LastException,
GetUtcdate(), -- WorkItemPoisened datetime
DELETED.WorkItemReceived_UTC
INTO dbo.FaildMessages
FROM dbo.WorkRequestQueue
WHERE
WorkRequestQueue.ID = #WorkRequestQueueID
IF ##ROWCOUNT = 0
RAISERROR ('Record not found', 16, 1)
SELECT Cast(SCOPE_IDENTITY() as int)
Any assistance would be most appreciated.
For now I use a workaround this like so.
declare #WorkRequestQueueID int
declare #LastException nvarchar(MAX)
set #WorkRequestQueueID = 7
set #LastException = 'test'
set nocount on
set xact_abort on
DECLARE #Failed TABLE
(
MessageEnvelope xml,
Attempts smallint,
LastException nvarchar(max),
WorkItemPoisened_UTC datetime,
WorkItemReceived_UTC datetime
)
BEGIN TRAN
DELETE dbo.WorkRequestQueue
OUTPUT
DELETED.MessageEnvelope,
DELETED.Attempts,
#LastException,
GetUtcdate(), -- WorkItemPoisened datetime
DELETED.WorkItemReceived_UTC
INTO
#Failed
FROM
dbo.WorkRequestQueue
WHERE
WorkRequestQueue.ID = #WorkRequestQueueID
IF ##ROWCOUNT = 0 BEGIN
RAISERROR ('Record not found', 16, 1)
Rollback
END ELSE BEGIN
insert into dbo.FaildMessages select * from #Failed
COMMIT TRAN
SELECT Cast(SCOPE_IDENTITY() as int)
END
EDITED FEB'2013
#MartinSmith alerts us that this bug don't want be fixed by Microsoft.
"Posted by Microsoft on 2/27/2013 at 2:18 PM Hello Martin, We
investigated the issue and found that changing the behavior is not an
easy thing to do. It would basically require redefining some of the
behavior when both INSERT & OUTPUT INTO target has identity columns.
Given the nature of the problem & the uncommon scenario, we have
decided not to fix the issue. -- Umachandar, SQL Programmability
Team"
EDITED OCT'2012
This is caused by a bug:
Testing bug:
Quoting OUTPUT Clause doc:
##IDENTITY, SCOPE_IDENTITY, and IDENT_CURRENT return identity values
generated only by the nested DML statement, and not those generated by
the outer INSERT statement.
After test it It seems that scope_identity() only works if outer operation is an insert in a table with identity columns:
Test 1: Delete
create table #t ( a char(1) );
create table #d ( a char(1), i int identity );
insert into #t
values ('a'),('b'),('c');
delete #t
output deleted.a into #d;
select SCOPE_IDENTITY(), * from #d;
a i
---- - -
null a 1
null b 2
null c 3
Test 2: Inserting in outer table with identity
create table #t ( a char(1), i int identity );
create table #d ( a char(1), i int identity );
insert into #t
values ('x'),('x'),('x');
insert into #t
output inserted.a into #d
values ('a'),('b');
select scope_identity(), * from #d;
a i
- - -
2 a 1
2 b 2
Test 3: Inserting in outer table without identity
create table #t ( a char(1) );
create table #d ( a char(1), i int identity );
insert into #t
values ('x'),('x'),('x');
insert into #t
output inserted.a into #d
values ('a'),('b');
select scope_identity(), * from #d;
a i
---- - -
null a 1
null b 2
You might try to use a table variable for your output clause, thus allowing you to explicitly insert into FaildMessages:
declare #WorkRequestQueueID int
declare #LastException nvarchar(MAX)
set #WorkRequestQueueID = 1
set #LastException = 'test'
set nocount off
-- Declare a table variable to capture output
DECLARE #output TABLE (
MessageEnvelope VARCHAR(50), -- Guessing at datatypes
Attempts INT, -- Guessing at datatypes
WorkItemReceived_UTC DATETIME -- Guessing at datatypes
)
-- Run the deletion with output
DELETE dbo.WorkRequestQueue
OUTPUT
DELETED.MessageEnvelope,
DELETED.Attempts,
DELETED.WorkItemReceived_UTC
-- Use the table var
INTO #output
FROM dbo.WorkRequestQueue
WHERE
WorkRequestQueue.ID = #WorkRequestQueueID
-- Explicitly insert
INSERT
INTO dbo.FaildMessages
SELECT
MessageEnvelope,
Attempts,
#LastException,
GetUtcdate(), -- WorkItemPoisened datetime
WorkItemReceived_UTC
FROM #output
IF ##ROWCOUNT = 0
RAISERROR ('Record not found', 16, 1)
SELECT Cast(SCOPE_IDENTITY() as int)

Resources