Trouble with OUTPUT statement. Incorrect Syntax - sql

I am trying to update a data set based on one conditional and then retrieving all the updated rows. VS keeps telling me there is an incorrect syntax error near my OUTPUT clause but I do not see anything wrong. I am just trying to figure out how to use "OUTPUT" so this may be a very stupid mistake I am making but failing to see.
What is wrong (syntactically) with this OUTPUT clause?
CREATE PROCEDURE [dbo].[GetInitialSessionNotifications]
#CurrentSessionId bigint
AS
DECLARE #tempTable table(
id bigint NOT NULL,
[Type] nvarchar,
DocumentCommentID bigint,
AnnouncmentID int,
EventID int,
MeetingID int,
[Read] bit,
RecieverId int,
AnnouncmentCommentId bigint,
EventCommentId bigint,
MeetingCommentId bigint,
DateAndTime DateTime);
UPDATE Notifications SET SessionId = #CurrentSessionId
WHERE SessionId != #CurrentSessionId
OUTPUT INSERTED.id,
INSERTED.[Type],
INSERTED.DocumentCommentID,
INSERTED.AnnouncmentID,
INSERTED.EventID,
INSERTED.MeetingID,
INSERTED.[Read],
INSERTED.RecieverId,
INSERTED.AnnouncmentCommentId,
INSERTED.EventCommentId,
INSERTED.MeetingCommentId,
INSERTED.DateAndTime
INTO #tempTable;
SELECT id, [Type], DocumentCommentId, AnnouncmentID, EventID, MeetingID,
[Read], RecieverId, AnnouncmentCommentId, EventCommentId, MeetingCommentId, DateAndTime
FROM #tempTable;
RETURN 0

Try this one -
CREATE PROCEDURE [dbo].[GetInitialSessionNotifications]
#CurrentSessionId BIGINT
AS BEGIN
DECLARE #tempTable TABLE
(
id BIGINT NOT NULL ,
[Type] NVARCHAR ,
DocumentCommentID BIGINT ,
AnnouncmentID INT ,
EventID INT ,
MeetingID INT ,
[Read] BIT ,
RecieverId INT ,
AnnouncmentCommentId BIGINT ,
EventCommentId BIGINT ,
MeetingCommentId BIGINT ,
DateAndTime DATETIME
)
UPDATE Notifications
SET SessionId = #CurrentSessionId
OUTPUT
INSERTED.id ,
INSERTED.[Type] ,
INSERTED.DocumentCommentID ,
INSERTED.AnnouncmentID ,
INSERTED.EventID ,
INSERTED.MeetingID ,
INSERTED.[Read] ,
INSERTED.RecieverId ,
INSERTED.AnnouncmentCommentId ,
INSERTED.EventCommentId ,
INSERTED.MeetingCommentId ,
INSERTED.DateAndTime
INTO #tempTable
WHERE SessionId != #CurrentSessionId
SELECT id ,
[Type] ,
DocumentCommentId ,
AnnouncmentID ,
EventID ,
MeetingID ,
[Read] ,
RecieverId ,
AnnouncmentCommentId ,
EventCommentId ,
MeetingCommentId ,
DateAndTime
FROM #tempTable;
END

Related

SQL IDENTITIY Column not starting with 1

I have a temp table in SQL 2014. In this table variable I have an identity column declared.
DECLARE #TempTable TABLE
(
ID int IDENTITY(1,1) PRIMARY KEY
, IncidentResolvedOn date
, IncidentCreatedOn date
, IncidentClosedOn date
, TaskAssigned date
, TaskCompleted date
, TaskID float
, IncidentTeamID int
, TotalDaysOutstanding int
, TierInfo varchar(15)
, Task_NoTask varchar(15)
, Tier_2_Days_Outstanding int
, Tier_1_Days_Outstanding int
, DaysToResolve int
, BadDays int
, StartDate date
, EndDate date
)
When I run the rest of the query the ID column sometimes doesn't start with 1, instead it starts with some random number. The code below is what I use to insert into this table variable.
INSERT INTO #TempTable(IncidentResolvedOn, IncidentCreatedOn, IncidentClosedOn,TaskAssigned, TaskCompleted, TaskID, IncidentTeamID )
SELECT [Incident Resolved On]
, [Incident Created On]
, [Incident Closed On]
, [Task Assigned On]
, [Task Completed On]
, [Task ID]
, IncidentTeamID
FROM HEATData
This happens in both a table variable and temp table. I've never seen this happen before. Usually when I use the IDENTITY(1,1) phrase it always starts with 1 no matter how many times I create that table. Any suggestions out there?
I imagine your connection is staying open and thus, your identity isn't resetting for your local variable. Here's an example.
DECLARE #TempTable TABLE
(
ID int IDENTITY(1,1) PRIMARY KEY,
ID2 int)
insert into #TempTable
values
(1),(2)
select * from #TempTable
delete from #TempTable
insert into #TempTable
values
(1),(2)
select * from #TempTable
Now, if you'd wrap this in it's own batch using GO you could see this wouldn't happen. In fact, you have to re-declare your table variable.
DECLARE #TempTable TABLE
(
ID int IDENTITY(1,1) PRIMARY KEY,
ID2 int)
insert into #TempTable
values
(1),(2)
select * from #TempTable
go
DECLARE #TempTable TABLE
(
ID int IDENTITY(1,1) PRIMARY KEY,
ID2 int)
insert into #TempTable
values
(1),(2)
select * from #TempTable
This would be the same for a #TempTable as well if you didn't explicitly drop the #TempTable or the connection remained open. Of course, for actual tables the increment will continue similarly to the first examaple.

Default to a value when a sub-query statement fails?

I have the following query:
INSERT INTO dbo.ResourceOrderCustomersOrders
( OrderId ,
Type ,
CustomerId ,
ResourceId ,
Quantity ,
Created ,
CreatedBy
)
VALUES ( ( SELECT MAX(OrderId) + 1
FROM dbo.ResourceOrderCustomersOrders
) , -- OrderId - int
'PENDING' , -- Type - varchar(50)
( SELECT MAX(CustomerId)
FROM dbo.ResourceOrderCustomers
WHERE UPPER(FirstName) = UPPER(#Firstname)
AND UPPER(Surname) = UPPER(#Surname)
AND UPPER(Email) = UPPER(#Email)
) , -- CustomerId - int
( SELECT MAX(ResourceId)
FROM dbo.ResourceOrderFormContent
WHERE DisplayTitle = #ResourceName
) , -- ResourceId - int
#ResourceQuantity ,
GETDATE() , -- Created - datetime
'WebsiteForm' -- CreatedBy - varchar(20)
);
In cases where a subquery fails I'd like to default to a value of my choosing (to hold unspecified records).
For example, were the following to fail to retrieve a result because a record doesn't exist:
SELECT MAX(ResourceId)
FROM dbo.ResourceOrderFormContent
WHERE DisplayTitle = #ResourceName
Then I would want to return the number '999' (unspecified record). What would be the best way to approach this?
I've tried to use try / catch but I'm being told this is invalid syntax. Here is my attempt:
INSERT INTO dbo.ResourceOrderCustomersOrders
( OrderId ,
Type ,
CustomerId ,
ResourceId ,
Quantity ,
Created ,
CreatedBy
)
VALUES ( ( SELECT MAX(OrderId) + 1
FROM dbo.ResourceOrderCustomersOrders
) , -- OrderId - int
'PENDING' , -- Type - varchar(50)
( SELECT MAX(CustomerId)
FROM dbo.ResourceOrderCustomers
WHERE UPPER(FirstName) = UPPER(#Firstname)
AND UPPER(Surname) = UPPER(#Surname)
AND UPPER(Email) = UPPER(#Email)
) , -- CustomerId - int
( BEGIN TRY
SELECT MAX(ResourceId)
FROM dbo.ResourceOrderFormContent
WHERE DisplayTitle = #ResourceName
END TRY
BEGIN CATCH
SELECT 999
END CATCH
) , -- ResourceId - int
#ResourceQuantity ,
GETDATE() , -- Created - datetime
'WebsiteForm' -- CreatedBy - varchar(20)
);
Max will always return NULL if no rows found. So You can use ISNULL.
SELECT ISNULL(MAX(ResourceId), 999)
FROM dbo.ResourceOrderFormContent
WHERE DisplayTitle = #ResourceName

Stored procedure how to cater NULL condition

I am reading a text file as an input to execute the logic in my stored procedure following is the sample of my textfile
<tblThreatenedSpeciesSubzone>
<ThreatenedSpeciesZoneID>-1</ThreatenedSpeciesZoneID>
<ManagementZoneID>0</ManagementZoneID>
<TSSubZoneNumber>BR101_Moderate/Good_Medium_1</TSSubZoneNumber>
<TSSubZoneArea>0</TSSubZoneArea>
<AdjacentRemnantVegArea>23</AdjacentRemnantVegArea>
<PatchArea>0</PatchArea>
<CreatedBySystemUser>BBCC Training 1</CreatedBySystemUser>
<UpdatedBySystemUser>BBCC Training 1</UpdatedBySystemUser>
<SaveType>1</SaveType>
<VegetationZoneID>-1</VegetationZoneID>
<ManagementZoneName />
</tblThreatenedSpeciesSubzone>
If you noticed <ManagementZoneName /> don't have any value. In my stored procedure I tried to find if Managementzone has value or not but not sure is the right way to do
IF #ManagementZoneIDInXML > 0 and ##ManagementZoneIDInXML <> NULL
BEGIN
INSERT INTO #tblThreatenedSpeciesSubzone
(ThreatenedSpeciesZoneID,
ManagementZoneID,
VegetationZoneID,
TSSubZoneNumber,
TSSubZoneArea,
AdjacentRemnantVegArea,
PatchArea,
DateCreated,
CreatedBySystemUser,
DateUpdated,
UpdatedBySystemUser,
SaveType,
RowTimestamp)
SELECT *
FROM OPENXML (#hDoc, '/NewDataSet/tblThreatenedSpeciesSubzone', 2)
WITH (ThreatenedSpeciesZoneID INT,
ManagementZoneID INT,
VegetationZoneID INT,
TSSubZoneNumber VARCHAR(50),
TSSubZoneArea NUMERIC(9,2),
AdjacentRemnantVegArea NUMERIC(9,2),
PatchArea NUMERIC(9,2),
DateCreated VARCHAR(50),
CreatedBySystemUser VARCHAR(50),
DateUpdated VARCHAR(50),
UpdatedBySystemUser VARCHAR(50),
SaveType INT,
RowTimestamp VARCHAR(50)) XMLDATA
WHERE
ManagementZoneID = #ManagementZoneIDInXML --Only select the rows that belong to the supplied ManagementZoneID
END
ELSE
BEGIN
INSERT INTO #tblThreatenedSpeciesSubzone
( ThreatenedSpeciesZoneID ,
ManagementZoneID ,
VegetationZoneID ,
TSSubZoneNumber ,
TSSubZoneArea ,
AdjacentRemnantVegArea ,
PatchArea ,
DateCreated ,
CreatedBySystemUser ,
DateUpdated ,
UpdatedBySystemUser ,
SaveType ,
RowTimestamp )
SELECT * FROM OPENXML (#hDoc, '/NewDataSet/tblThreatenedSpeciesSubzone', 2)
WITH ( ThreatenedSpeciesZoneID INT ,
ManagementZoneID INT ,
VegetationZoneID INT ,
TSSubZoneNumber VARCHAR(50) ,
TSSubZoneArea NUMERIC(9,2) ,
AdjacentRemnantVegArea NUMERIC(9,2) ,
PatchArea NUMERIC(9,2) ,
DateCreated VARCHAR(50) ,
CreatedBySystemUser VARCHAR(50) ,
DateUpdated VARCHAR(50) ,
UpdatedBySystemUser VARCHAR(50) ,
SaveType INT ,
RowTimestamp VARCHAR(50) ) XMLDATA
WHERE VegetationZoneID = #VegetationZoneIDInXML --Only select the rows that belong to the supplied VegetationZoneID
--And no Management zone assigned
END

How to pass constant value in stored procedure

I have the following statement inside a stored procedure:
INSERT INTO #tblThreatenedSpeciesSubzone
(ThreatenedSpeciesZoneID,
ManagementZoneID,
VegetationZoneID)
SELECT *
FROM OPENXML (#hDoc, '/NewDataSet/tblThreatenedSpeciesSubzone', 2)
WITH (ThreatenedSpeciesZoneID INT,
ManagementZoneID INT,
VegetationZoneID INT) XMLDATA
WHERE VegetationZoneID = #VegetationZoneIDInXML
Sometime "managementZone id" becomes null, I want to replace if it is null then I want pass the constant value "0". Is there a way to do ?
Not sure about "passing a constant value", but you can always set a default:
CREATE PROCEDURE Sales.uspGetSalesYTD
#SalesPerson nvarchar(50) = 'Andersson' -- default value
AS
So:
#ManagementZoneID INT = 0
You could use a coalesce in the select statement
INSERT INTO #tblThreatenedSpeciesSubzone
( ThreatenedSpeciesZoneID ,
ManagementZoneID ,
VegetationZoneID
)
SELECT
ThreatenedSpeciesZoneID ,
COALESCE(ManagementZoneID,0) ,
VegetationZoneID
FROM OPENXML (#hDoc, '/NewDataSet/tblThreatenedSpeciesSubzone', 2)
WITH ( ThreatenedSpeciesZoneID INT ,
ManagementZoneID INT ,
VegetationZoneID INT ) XMLDATA
WHERE VegetationZoneID = #VegetationZoneIDInXML

Share auto-increment value from SQL stored procedure

I have a stored procedure that inserts data on a table with an auto-increment id (name of 'requestid'). As I insert data into it using the procedure, I want to take the value of the auto-increment field and use it on another query to the same stored procedure. How do I do that? Thank you in advance for your time.
CREATE PROCEDURE [dbo].[sp_Create_new_request]
#employeeid INT ,
#requestdate DATETIME ,
#deliverdate DATETIME ,
#totalcost MONEY
AS
BEGIN
INSERT INTO dbo.Requests
(
EmployeeID ,
RequestDate ,
DeliverDate ,
TotalCost
)
VALUES
(
#employeeid ,
#requestdate ,
#deliverdate ,
#totalcost
)
END
Try
CREATE PROCEDURE [dbo].[sp_Create_new_request]
#employeeid INT ,
#requestdate DATETIME ,
#deliverdate DATETIME ,
#totalcost MONEY,
requestid INT = NULL OUT
AS
BEGIN
INSERT INTO dbo.Requests
(
EmployeeID ,
RequestDate ,
DeliverDate ,
TotalCost
)
VALUES
(
#employeeid ,
#requestdate ,
#deliverdate ,
#totalcost
)
SET #requestid = SCOPE_IDENTITY();
END
You should not use auto increment instead use sequence to increment and then you can reuse that value anywhere.
You can use also :
IDENT_CURRENT ('dbo.Requests')
Information about IDENT_CURRENT
http://technet.microsoft.com/en-us/library/ms175098.aspx