multiple declare statements with one creating a temporary table - sql-server

I am trying to include a declare statement referencing a temporary table with other declare statements. It works on its own, but when I add the remaining declare clauses, I get an error...
declare #meas_enddate datetime,
#meas_startdate datetime,
#enc_startdate
datetime,
#enc_enddate datetime,
#activestart datetime,
#activeend datetime,
#baseline_start datetime,
#baseline_end datetime,
#Dept as Table (DEPARTMENT_ID numeric(18,0) NOT NULL PRIMARY KEY,
UNIQUE NONCLUSTERED (DEPARTMENT_ID))
INSERT INTO #Dept
SELECT
'100501201'
UNION SELECT '100208501'
UNION SELECT '100302304'...

try seperating table variable creation like below
declare #id1 int
declare #id table
(
id int
)
select * from #id
instead of
declare #id1 int,
#id table
(
id int
)
select * from #id
this has been mentioned in Docs :DECLARE (Transact-SQL)
When declaring table variables, the table variable must be the only variable being declared in the DECLARE statement.

Try this notice the semicolon after #baseline_end and delcare in front of #Dept
declare #meas_enddate datetime,
#meas_startdate datetime,
#enc_startdate datetime,
#enc_enddate datetime,
#activestart datetime,
#activeend datetime,
#baseline_start datetime,
#baseline_end datetime;
declare #Dept as Table (DEPARTMENT_ID numeric(18,0) NOT NULL PRIMARY KEY,
UNIQUE NONCLUSTERED (DEPARTMENT_ID))
INSERT INTO #Dept
SELECT
'100501201'
UNION SELECT '100208501'
UNION SELECT '100302304'

Related

Simple insert stored procedure not working

I am trying to make a simple stored procedure but it's not working. When I execute the procedure with my parameters in it, below is the following:
ALTER proc [dbo].[sp_NewProduct]
#ProductName nvarchar(50),
#ProductNumber nvarchar(25),
#MakeFlag bit,
#FinishedGoodsFlag bit,
#Color nvarchar(15),
#SafetyStockLevel smallint,
#ReorderPoint smallint,
#StandardCost money,
#ListPrice money,
#DaysToManufacture int,
#SellStartDate date,
#rowguid uniqueidentifier,
#ModifiedDate datetime
as
insert dbo.product
(Name,
ProductNumber,
MakeFlag,
FinishedGoodsFlag,
Color,
SafetyStockLevel,
ReorderPoint,
StandardCost,
ListPrice,
DaysToManufacture,
SellStartDate,
rowguid,
ModifiedDate)
values
(#ProductName,
#ProductNumber,
#MakeFlag,
#FinishedGoodsFlag,
#Color, #SafetyStockLevel,
#ReorderPoint,
#StandardCost,
#ListPrice,
#DaysToManufacture,
#SellStartDate,
#rowguid,
#ModifiedDate)
Here's the execute query with values of each column:
exec sp_NewProduct 'AR-5516','105',0,1,'Red',5,5,0.00,0.00,5,'2018-05-01',newid(),getdate()
Seems you are dealing with wrong procedure syntax! use following snippets:
Create or Alter proc [dbo].[sp_NewProduct] (#ProductName nvarchar(50), #ProductNumber nvarchar(25), #MakeFlag bit, #FinishedGoodsFlag bit, #Color nvarchar(15), #SafetyStockLevel smallint, #ReorderPoint smallint, #StandardCost money, #ListPrice money, #DaysToManufacture int, #SellStartDate date, #rowguid uniqueidentifier, #ModifiedDate datetime)
As
Begin
Insert dbo.product (Name,ProductNumber,MakeFlag,FinishedGoodsFlag,Color,SafetyStockLevel,ReorderPoint,StandardCost,ListPrice, DaysToManufacture,SellStartDate,rowguid,ModifiedDate) values (#ProductName,#ProductNumber,#MakeFlag,#FinishedGoodsFlag,#Color, #SafetyStockLevel,#ReorderPoint,#StandardCost,#ListPrice,#DaysToManufacture,#SellStartDate,#rowguid,#ModifiedDate)
End
Go
Exec sp_NewProduct 'AR-5516','105',0,1,'Red',5,5,0.00,0.00,5,'2018-05-01',#Id,#DateTime;
If you still getting error, store newid()'s value and GetDate()'s value in temporary variable, and call through this variable!
Declare #Id AS UniqueIdentifier = NewId()
Declare #DateTime as DateTime = GetDate()
Exec sp_NewProduct 'AR-5516','105',0,1,'Red',5,5,0.00,0.00,5,'2018-05-01',#Id,#DateTime;

Triggers not working when inserting data through OPEN XML in sql ser

I have created a trigger for a asset_verification. Whenever a new record is inserted in this table, the same record is inserted in the asset_verification_history table because of this trigger.
The trigger is as follows
Create trigger [dbo].[tr_insert_after_asset_verification] on [dbo].[asset_verification]
for insert
As
Begin
declare #verification_id int
declare #id int
declare #audit_id int
declare #date date
declare #status varchar(15)
declare #remarks varchar(200)
declare #creationDate datetime
declare #modificationDate datetime
declare #updatedBy int
declare #audit_action varchar(20)
Select #verification_id = i.verification_id from inserted i
If #verification_id IS NOT NULL
Begin
Select #id = i.id from inserted i
Select #audit_id = i.audit_id from inserted i
Select #date = i.date from inserted i
Select #status = i.status from inserted i
Select #remarks = i.remarks from inserted i
Select #creationDate = i.creationDate from inserted i
Select #modificationDate = i.modificationDate from inserted i
Select #updatedBy = i.updatedBy from inserted i
set #audit_action = 'Insert Record'
INSERT INTO [dbo].[asset_verification_history]
([verification_id]
,[id]
,[audit_id]
,[date]
,[status]
,[remarks]
,[creationDate]
,[modificationDate]
,[updatedBy]
,[audit_action])
VALUES
(#verification_id
,#id
,#audit_id
,#date
,#status
,#remarks
,#creationDate
,#modificationDate
,#updatedBy
,#audit_action)
End
End
When I insert the data in the asset_verification table using a procedure in which OPEN XML is used, then this trigger works only for the first record. For the rest of the records the trigger doesn't work
The procedure is as follows
Create procedure [dbo].[usp_AddVerificationBulkData]
(
#vXML XML
)
As
Begin
DECLARE #DocHandle INT
SET NOCOUNT ON
EXEC sp_xml_preparedocument #DocHandle OUTPUT, #vXML
Update asset_verification
set
audit_id = x.AuditId,
id = x.SerialId,
date = x.VerificationDate,
status = x.Status
,remarks = x.Remarks
,creationDate = x.CreatedOn
,modificationDate = x.ModifiedOn
,updatedBy = x.ModifiedBy
From
asset_verification a
Inner Join
OpenXml(#DocHandle,'/ArrayOfAssetVerificationModel/AssetVerificationModel',2)
With(SerialId int, AuditId int, VerificationDate datetime, Status int, Remarks varchar(200), CreatedOn datetime, ModifiedOn datetime, ModifiedBy int) x
On a.audit_id = x.AuditId where a.id = x.SerialId;
INSERT INTO [dbo].[asset_verification]
([id]
,[audit_id]
,[date]
,[status]
,[remarks]
,[creationDate]
,[modificationDate]
,[updatedBy])
select SerialId,AuditId,VerificationDate,Status,Remarks,CreatedOn,ModifiedOn,ModifiedBy from OpenXml(#DocHandle,'/ArrayOfAssetVerificationModel/AssetVerificationModel',2)
With(SerialId int, AuditId int, VerificationDate datetime, Status int, Remarks varchar(200), CreatedOn datetime, ModifiedOn datetime, ModifiedBy int) x
where SerialId NOT IN (select a.id from asset_verification a where a.audit_id = x.AuditId);
End
Problem:- How to make this trigger work for every record that is inserted through Open XML ?
You've made the classic mistake of thinking that triggers fire once-per-row. They dont, it's once-per-action, so the inserted pseudo table holds all the rows affected by the action. Your trigger needs to work in a set based manner, not row based. Try this;
CREATE TRIGGER [dbo].[tr_insert_after_asset_verification] ON [dbo].[asset_verification] FOR INSERT AS
BEGIN
SET NOCOUNT ON
INSERT INTO [dbo].[asset_verification_history]
( [verification_id]
,[id]
,[audit_id]
,[date]
,[status]
,[remarks]
,[creationDate]
,[modificationDate]
,[updatedBy]
,[audit_action]
)
SELECT i.verification_id
,i.id
,i.audit_id
,i.date
,i.status
,i.remarks
,i.creationDate
,i.modificationDate
,i.updatedBy
,'Insert Record'
FROM inserted i
WHERE i.verification_id IS NOT NULL
END
As an aside, and strictly speaking, your original trigger will log one row, not necessarily the first.

In stored procedure if null value found it should skip that insert query

I have 2 tables one is
peson contains(personid Identity, firstname,Lastname,PlaceOfBirth,Gender)
and another
Education contains (Eduid identity, egreename,boardUniver,yearOfPassing,obtainedMarks, personid)
now my problem is that each person have more than 1 degree, but some have 1 or 2 degree, so how can i skip the insert queries?
First Table
Create table person(personid int Identity(1,1) primary key, firstname nvarchar(40), Lastname nvarchar(40), PlaceOfBirth nvarchar(40), Gender nvarchar(10))
Second Table
create table Education(Eduid int identity(1,1) primary key, Degreename nvarchar(40), boardUniver nvarchar(40), yearOfPassing nvarchar(40), obtainedMarks numeric(10,2), personid int,
constraint fk_eduPerson foreign key (personid) references person(personid))
Procedure to store information
Create procedure EmpDetails
(
#Firstname nvarchar(40), #Lastname nvarchar(40), #PlaceOfBirth nvarchar(40), #Gender nvarchar(8),
#Degreename0 int, #boardUniver0 nvarchar(40), #yearOfPassing0 nvarchar(20), #obtainedMarks0 int,
#Degreename1 int, #boardUniver1 nvarchar(40), #yearOfPassing1 nvarchar(20), #obtainedMarks1 int,
#Degreename2 int, #boardUniver2 nvarchar(40), #yearOfPassing2 nvarchar(20), #obtainedMarks2 int,
)
AS BEGIN
declare #personid int
INSERT INTO person(firstname,Lastname,PlaceOfBirth,Gender) values(#firstname,#Lastname,#PlaceOfBirth,#Gender)
SELECT #personid=##IDENTITY
if(#Degreename0 !=NULL)
BEGIN
INSERT INTO Education(Degreename,boardUniver,yearOfPassing,obtainedMarks, personid) values (#Degreename0,#boardUniver0,#yearOfPassing0,#obtainedMarks0, #personid)
END
IF(#Degreename1 !=null)
BEGIN
INSERT INTO Education(Degreename,boardUniver,yearOfPassing,obtainedMarks, personid) values (#Degreename1,#boardUniver1,#yearOfPassing1,#obtainedMarks1, #personid)
END
IF(#Degreename2!=null)
BEGIN
INSERT INTO Education(Degreename,boardUniver,yearOfPassing,obtainedMarks, personid) values (#Degreename2,#boardUniver2,#yearOfPassing2,#obtainedMarks2,#personid)
END
END
This is not working.. this inserts all rows empty.. is there any other solution to do this?
Please give suggestion if any other.. Thanks
Try IS NOT NULL instead of != NULL. In most relational databases, the comparison operators return false if either input is NULL, even if they both are. Here is a SQL Fiddle demonstrating the behavior.
(Sorry. That SQL Fiddle really works.)
Admittedly, this is confusing, as that fact should mean all your INSERTs are skipped. I don't see anything here that would insert empty rows.
Try this one -
Create procedure EmpDetails
(
...
)
AS BEGIN
DECLARE #personid INT
INSERT INTO Person (firstname, Lastname, PlaceOfBirth, Gender)
SELECT #firstname, #Lastname, #PlaceOfBirth, #Gender
SELECT #personid = SCOPE_IDENTITY()
INSERT INTO Education (Degreename, boardUniver, yearOfPassing, obtainedMarks, PersonID)
SELECT a = #Degreename0, b = #boardUniver0, c = #yearOfPassing0, d = #obtainedMarks0, e = #personid
WHERE #Degreename0 IS NOT NULL
UNION ALL
SELECT #Degreename1, #boardUniver1, #yearOfPassing1, #obtainedMarks1, #personid
WHERE #Degreename1 IS NOT NULL
UNION ALL
SELECT #Degreename2, #boardUniver2, #yearOfPassing2, #obtainedMarks2, #personid
WHERE #Degreename2 IS NOT NULL
END

Pivot with a table variable

I'm unable to use a pivot the data of a table variable.
Its giving following error on run-time:
"Must declare the scalar variable #reportData"
I have tried as mentioned below
DECLARE #reportData TABLE
(
PERSONID NUMERIC(6,0),
personname VARCHAR(100),
bu VARCHAR(50),
timeperiod VARCHAR(100),
wfstatus VARCHAR(100)
)
I'm using the below dynamic pivot query
declare #query nvarchar(max)
set #query=N'SELECT PERSONID,PERSONNAME,BU,wfstatus,'+#datelist+'
from(
SELECT PERSONID,PERSONNAME,BU,wfstatus,timeperiod
FROM
'+#reportData+') AS SOURCETABLE
PIVOT
(group by wfstatus
FOR timeperiod
IN('+#datelist+')
) as pivorttable
select personid,personname,bu,timeperiod,status from pivorttable'
execute(#query);
can some one help me in this?
I need to use only table variable to maintain concurrency issue.!
FROM'+#reportData attempts to add a table variable to a string, which wont work as a table variable is not a string.
Given that you presumably need to populate reportData first you could switch to an explicitly created temp table
create table #reportData
(
PERSONID NUMERIC(6,0)
...
)
Or use a Table Type;
--run once
CREATE TYPE ReportDataType AS TABLE (
PERSONID NUMERIC(6,0),
personname VARCHAR(100)
)
declare #reportData ReportDataType
insert #reportData values
(111, 'bob'),
(222, 'alice')
declare #query nvarchar(max) = N'select * from #T'
exec sp_executesql #query, N'#T ReportDataType readonly', #reportData

SCOPE IDENTITY not allowed on a REMOTE server?

I am trying to copy data from 2 tables linked by a foreign key on one server and then inserted them into the master database on another server.
The first table will generate a new IDENTITY column and then I want to store this in a variable and insert it into the 2nd table.
I have tried both using internal inserted tables and also SCOPE_IDENTITY() but receive errors that this is not allowed on a REMOTE server
DECLARE
#VisitSourceId int,
#SiteDomainId int,
#trpUTMid bigint,
#FlightPlus bit,
#StartDate datetime,
#CountryId int,
#ProvinceId int,
#Locationid int,
#PlaceId int,
#EstabId int,
#CheckInDate smalldatetime,
#CheckOutDate smalldatetime,
#Rooms int,
#Room1Adults int,
#Room1Children int,
#Room2Adults int,
#Room2Children int,
#Room3Adults int,
#Room3Children int,
#OutcomeDate datetime,
#OutcomeId smallint,
#HotelsFound smallint,
#Notes nvarchar,
#id bigint
DECLARE c CURSOR STATIC FOR
SELECT t.VisitSourceId, t.SiteDomainId, t.trpUTMid, t.FlightPlus, t.StartDate, t.CountryId, t.ProvinceId, t.Locationid,
t.PlaceId, t.EstabId, t.CheckInDate, t.CheckOutDate, t.Rooms, t.Room1Adults, t.Room1Children, t.Room2Adults, t.Room2Children, t.Room3Adults,
t.Room3Children, tc.OutcomeDate, tc.OutcomeId, tc.HotelsFound, tc.Notes
FROM [MLT_VisitTracking].[dbo].TrackingAcomSearches_tbl t
INNER JOIN TrackingAcomSearchesOutcome_tbl tc
ON t.trpUTMid = tc.trpUTMid
open c
FETCH FIRST FROM c INTO #VisitSourceId, #SiteDomainId, #trpUTMid, #FlightPlus, #StartDate, #CountryId, #ProvinceId, #Locationid,
#PlaceId, #EstabId, #CheckInDate, #CheckOutDate, #Rooms, #Room1Adults, #Room1Children, #Room2Adults, #Room2Children, #Room3Adults,
#Room3Children, #OutcomeDate, #OutcomeId, #HotelsFound, #Notes
while ##fetch_status=0
begin
DECLARE #TmpTable TABLE (ID BIGINT)
INSERT INTO [YAZOO].[MLT_VisitTracking].[dbo].TrackingAcomSearches_tbl
(VisitSourceId, SiteDomainId, trpUTMid, FlightPlus, StartDate, CountryId, ProvinceId, Locationid,
PlaceId, EstabId, CheckInDate, CheckOutDate, Rooms, Room1Adults, Room1Children, Room2Adults, Room2Children, Room3Adults,
Room3Children)
OUTPUT inserted.searchid into #TmpTable
SELECT #VisitSourceId, #SiteDomainId, #trpUTMid, #FlightPlus, #StartDate, #CountryId, #ProvinceId, #Locationid,
#PlaceId, #EstabId, #CheckInDate, #CheckOutDate, #Rooms, #Room1Adults, #Room1Children, #Room2Adults, #Room2Children, #Room3Adults,
#Room3Children
select top 1 #id = searchid from #tmptable
INSERT INTO [YAZOO].[MLT_VisitTracking].[dbo].TrackingAcomSearchesOutcome_tbl
(SearchId,
trpUTMid,
OutcomeDate,
OutcomeId,
HotelsFound,
Notes)
SELECT #id,
#trpUTMid,
#OutcomeDate,
#OutcomeId,
#HotelsFound,
#Notes
DELETE FROM [MLT_VisitTracking].[dbo].TrackingAcomSearches_tbl WHERE trpUTMid=#trpUTMid
DELETE FROM [MLT_VisitTracking].[dbo].TrackingAcomSearchesOutcome_tbl WHERE trpUTMid=#trpUTMid
FETCH NEXT FROM c INTO #VisitSourceId, #SiteDomainId, #trpUTMid, #FlightPlus, #StartDate, #CountryId,
#ProvinceId, #Locationid, #PlaceId, #EstabId, #CheckInDate, #CheckOutDate, #Rooms, #Room1Adults, #Room1Children,
#Room2Adults, #Room2Children, #Room3Adults, #Room3Children, #OutcomeDate, #OutcomeId, #HotelsFound, #Notes
end
close c
deallocate c
##IDENTITY and SCOPE_IDENTITY() are local
are you using a linked server?
check this:
get ##Identity from another server(linked server)
To resolve the issue I finally created the script on the target server as a stored procedure, then I could use scope identity. The performance also improved massively, I then configured a new linked server with RPC out enabled and called the procedure remotely. It is not an elegant solution, but its only temporary

Resources