DDL Trigger execution error on schema changes - sql

I created DDL triggers for SQL Server. After doing some DDL operations like create/alter/drop table, i am getting this following error - 'An error was raised during trigger execution. The batch has been aborted and the user transaction, if any, has been rolled back'. Can anyone help me with it.
Here is the trigger creation script -
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [tr_SCHEMA_CHANGES]
ON DATABASE
FOR DDL_DATABASE_LEVEL_EVENTS
AS
BEGIN
SET NOCOUNT ON;
IF OBJECT_ID('dbo.SCHEMA_CHANGES') IS NOT NULL
BEGIN
BEGIN TRY
DECLARE #Eventdata XML;
SET #Eventdata = EVENTDATA();
INSERT dbo.SCHEMA_CHANGES (
[DateTime]
, [ServerName]
, [ServiceName]
, [SPID]
, [SourceHostName]
, [LoginName]
, [UserName]
, [SchemaName]
, [TABLE_NAME]
, [TargetObjectName]
, [EVENT_TYPE]
, [ObjectType]
, [TargetObjectType]
, [EventData]
, [COMMAND_TEXT]
, [ReplicationAuditId]
, [ReplicationOperation]
, [ReplicationDateTime]
, [RowState]
)
VALUES (
GETUTCDATE()
, ##SERVERNAME
, ##SERVICENAME
, #Eventdata.value('(/EVENT_INSTANCE/SPID)[1]', 'int')
, HOST_NAME()
, #Eventdata.value('(/EVENT_INSTANCE/LoginName)[1]', 'nvarchar(128)')
, #Eventdata.value('(/EVENT_INSTANCE/UserName)[1]', 'nvarchar(128)')
, #Eventdata.value('(/EVENT_INSTANCE/SchemaName)[1]', 'nvarchar(128)')
, #Eventdata.value('(/EVENT_INSTANCE/ObjectName)[1]', 'nvarchar(128)')
, #Eventdata.value('(/EVENT_INSTANCE/TargetObjectName)[1]', 'nvarchar(128)')
, #Eventdata.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(128)')
, #Eventdata.value('(/EVENT_INSTANCE/ObjectType)[1]', 'nvarchar(128)')
, #Eventdata.value('(/EVENT_INSTANCE/TargetObjectType)[1]', 'nvarchar(128)')
, #Eventdata
, #Eventdata.value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]', 'nvarchar(MAX)')
, 0
,'Schema Replication'
, GETUTCDATE()
,'queued'
);
END TRY
BEGIN CATCH
SET #Eventdata= NULL;
END CATCH
END
END
GO
ENABLE TRIGGER [tr_SCHEMA_CHANGES] ON DATABASE
GO
Tried with changes script but same error

Related

SQL Server transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements

In the below stored procedure, I'm getting the error mentioned in some cases, what am I doing wrong here?
Error:
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1
Stored procedure:
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
CREATE PROCEDURE [dbo].[prcInsDataFeesForVersion]
(#ContractId INT,
#UserId INT,
#VersionNo INT,
#SelectAll BIT,
#SubProductList NVARCHAR(MAX),
#ConvRateFlag BIT)
AS
BEGIN
SET NOCOUNT ON
DECLARE #RetVal INT,
#ErrMsg VARCHAR(255),
#FunctionId INT = 1234,
#AppId VARCHAR(20) = 'ID1021',
#FeesOverrideFlg BIT = 1,
#ContractProdFeeVerSummId INT
CREATE TABLE #tblMasterData
(
ProdCd INT,
ProdName NVARCHAR(255),
SubProdCd INT,
SubProdName NVARCHAR(255),
ProdTypeCd INT,
ProdDeliveryTypCd INT,
ProdStatusCd INT,
ProdStatusDt DATETIME,
CreatedDate DATETIME
)
CREATE TABLE #tblContractInterCulturalDataFiltered
(
ContractID INT
, ContractProdID INT
, ProdCd INT
, ProdName NVARCHAR(255)
, ContractSubProdID INT
, SubProdCd INT
, SubProdName NVARCHAR(255)
, ContractProdStatusCd INT
, ContractProdStatusDt DATETIME
, ContractSubProdStatusCd INT
, ContractSubProdStatusDt DATETIME
, ContractProdFeeId INT
, FeeTypCd INT
, RowMatrixParameterCd INT
, CreatedDate DATETIME
)
CREATE TABLE #tblContractInterCulturalDataFilteredInsert
(
ContractID INT
, ContractProdID INT
, ProdCd INT
, ProdName NVARCHAR(255)
, ContractSubProdID INT
, SubProdCd INT
, SubProdName NVARCHAR(255)
, ContractProdStatusCd INT
, ContractProdStatusDt DATETIME
, ContractSubProdStatusCd INT
, ContractSubProdStatusDt DATETIME
, FeeTypCd INT
, FeeDeterminantCd INT
, RowMatrixParameterCd INT
, ProdFeeCurrCd INT
, RowParameterValueCd INT
, ColumnParameterValueCd INT
, ProdFeePct REAL
, RangeFromDayCnt INT
, RangeToDayCnt INT
, ProdFeeLevelMinAmt DECIMAL
, ProdFeeLevelMaxAmt DECIMAL
, ProdFeeAmt DECIMAL
, ContractProdFeeId INT
, CreatedDate DATETIME
)
CREATE TABLE #tblContractInterCulturalDataFilteredUpdate
(
ContractID INT
, ContractProdID INT
, ProdCd INT
, ProdName NVARCHAR(255)
, ContractSubProdID INT
, SubProdCd INT
, SubProdName NVARCHAR(255)
, ContractProdStatusCd INT
, ContractProdStatusDt DATETIME
, ContractSubProdStatusCd INT
, ContractSubProdStatusDt DATETIME
, FeeTypCd INT
, FeeDeterminantCd INT
, RowMatrixParameterCd INT
, ProdFeeCurrCd INT
, RowParameterValueCd INT
, ColumnParameterValueCd INT
, ProdFeePct REAL
, RangeFromDayCnt INT
, RangeToDayCnt INT
, ProdFeeLevelMinAmt DECIMAL
, ProdFeeLevelMaxAmt DECIMAL
, ProdFeeAmt DECIMAL
, ContractProdFeeId INT
, CreatedDate DATETIME
)
CREATE TABLE #tblSelContractSubProds
(
ContractSubProdId INT
)
BEGIN TRY
BEGIN TRANSACTION
IF(#SelectAll=0 AND #SubProductList IS NOT NULL)
BEGIN
INSERT INTO #tblSelContractSubProds
SELECT intValue FROM dbo.udfSplit(#SubProductList,',',1)
END
INSERT INTO #tblMasterData(
ProdCd
, ProdName
, SubProdCd
, SubProdName
, ProdTypeCd
, ProdDeliveryTypCd
, ProdStatusCd
, ProdStatusDt
, CreatedDate
)
SELECT P.ProdCd
, PC.Descr
, S.SubProdCd
, SC.Descr
, P.ProdTypeCd
, P.ProdDeliveryTypCd
, P.ProdStatusCd
, P.ProdStatusDt
, GETDATE()
FROM tblProduct(NOLOCK) as P
INNER JOIN tblCode(NOLOCK) as PC ON P.ProdCd=PC.Cd and PC.Typ=1053
INNER JOIN tblSubProdDetail(NOLOCK) as S ON P.ProdCd=S.ProdCd
INNER JOIN tblCode(NOLOCK) as SC ON S.SubProdCd=SC.Cd and SC.Typ=1053
WHERE P.ProdDeliveryTypCd=3 and P.ProdStatusCd=1
IF(#SelectAll=1)
BEGIN
INSERT INTO #tblContractInterCulturalDataFiltered(
ContractID
, ContractProdID
, ProdCd
, ProdName
, ContractSubProdID
, SubProdCd
, SubProdName
, ContractProdStatusCd
, ContractProdStatusDt
, ContractSubProdStatusCd
, ContractSubProdStatusDt
, ContractProdFeeId
, FeeTypCd
, RowMatrixParameterCd
, CreatedDate
)
SELECT DISTINCT CP.ContractId,
CP.ContractProdId,
CP.ProdCd,
CPC.Descr,
CSP.ContractSubProdID,
CSP.SubProdCd,
CSPC.Descr,
CP.ContractProdStatusCd,
CP.ContractProdStatusDt,
CSP.ContractSubProdStatusCd,
CSP.ContractSubProdStatusDt,
CPF.ContractProdFeeId,
CPF.FeeTypCd,
CPF.RowMatrixParameterCd,
Getdate()
FROM #tblMasterData(NOLOCK) MD
INNER JOIN tblContractProd(NOLOCK) CP ON MD.ProdCd=CP.ProdCd
INNER JOIN tblContractSubProd(NOLOCK) CSP ON CP.ContractProdId=CSP.ContractProdId
INNER JOIN tblCode(NOLOCK) CPC ON CP.ProdCd=CPC.Cd and CPC.Typ=1053
INNER JOIN tblCode(NOLOCK) CSPC ON CSP.SubProdCd=CSPC.Cd and CSPC.Typ=1053
INNER JOIN tblContractProdFee(NOLOCK) CPF ON CP.ContractProdID=CPF.ContractProdId AND CSP.ContractSubProdID=CPF.ContractSubProdId
WHERE ContractId=#ContractId AND CP.ContractProdStatusCd=1 AND CSP.ContractSubProdStatusCd=1
AND CPF.ContractProdFeeTypStatusCd=1 AND CP.StandardProdIndCd=1 AND CSP.StdSubProdIndCd=1
END
ELSE
BEGIN
IF(#SubProductList IS NOT NULL)
BEGIN
INSERT INTO #tblContractInterCulturalDataFiltered(
ContractID
, ContractProdID
, ProdCd
, ProdName
, ContractSubProdID
, SubProdCd
, SubProdName
, ContractProdStatusCd
, ContractProdStatusDt
, ContractSubProdStatusCd
, ContractSubProdStatusDt
, ContractProdFeeId
, FeeTypCd
, RowMatrixParameterCd
, CreatedDate
)
SELECT DISTINCT CP.ContractId,
CP.ContractProdId,
CP.ProdCd,
CPC.Descr,
CSP.ContractSubProdID,
CSP.SubProdCd,
CSPC.Descr,
CP.ContractProdStatusCd,
CP.ContractProdStatusDt,
CSP.ContractSubProdStatusCd,
CSP.ContractSubProdStatusDt,
CPF.ContractProdFeeId,
CPF.FeeTypCd,
CPF.RowMatrixParameterCd,
Getdate()
FROM #tblMasterData(NOLOCK) MD
INNER JOIN tblContractProd(NOLOCK) CP ON MD.ProdCd=CP.ProdCd
INNER JOIN tblContractSubProd(NOLOCK) CSP ON CP.ContractProdId=CSP.ContractProdId
INNER JOIN tblCode(NOLOCK) CPC ON CP.ProdCd=CPC.Cd and CPC.Typ=1053
INNER JOIN tblCode(NOLOCK) CSPC ON CSP.SubProdCd=CSPC.Cd and CSPC.Typ=1053
INNER JOIN tblContractProdFee(NOLOCK) CPF ON CP.ContractProdID=CPF.ContractProdId AND CSP.ContractSubProdID=CPF.ContractSubProdId
INNER JOIN #tblSelContractSubProds(NOLOCK) SCSP ON CSP.ContractSubProdId=SCSP.ContractSubProdId
WHERE ContractId=#ContractId AND CP.ContractProdStatusCd=1 AND CSP.ContractSubProdStatusCd=1
AND CPF.ContractProdFeeTypStatusCd=1 AND CP.StandardProdIndCd=1 AND CSP.StdSubProdIndCd=1
END
END
INSERT INTO #tblContractInterCulturalDataFilteredUpdate(
ContractID
, ContractProdID
, ProdCd
, ProdName
, ContractSubProdID
, SubProdCd
, SubProdName
, ContractProdStatusCd
, ContractProdStatusDt
, ContractSubProdStatusCd
, ContractSubProdStatusDt
, FeeTypCd
, FeeDeterminantCd
, RowMatrixParameterCd
, ProdFeeCurrCd
, RowParameterValueCd
, ColumnParameterValueCd
, ProdFeePct
, RangeFromDayCnt
, RangeToDayCnt
, ProdFeeLevelMinAmt
, ProdFeeLevelMaxAmt
, ProdFeeAmt
, ContractProdFeeId
, CreatedDate
)
SELECT DISTINCT CICF.ContractId,
CICF.ContractProdId,
CICF.ProdCd,
CICF.ProdName,
CICF.ContractSubProdID,
CICF.SubProdCd,
CICF.SubProdName,
CICF.ContractProdStatusCd,
CICF.ContractProdStatusDt,
CICF.ContractSubProdStatusCd,
CICF.ContractSubProdStatusDt,
CPFM.FeeTypCd,
CPFM.FeeDeterminantCd,
CPFM.RowMatrixParameterCd,
CPFM.ProdFeeCurrCd,
CPFM.RowParameterValueCd,
CPFM.ColumnParameterValueCd,
CPFM.ProdFeePct,
CPFM.RangeFromDayCnt,
CPFM.RangeToDayCnt,
CPFM.ProdFeeLevelMinAmt,
CPFM.ProdFeeLevelMaxAmt,
CPFM.ProdFeeAmt,
CICF.ContractProdFeeId,
Getdate()
FROM #tblContractInterCulturalDataFiltered(NOLOCK) CICF
INNER JOIN tblContractProdFeeMatrix(NOLOCK) CPFM ON CICF.ProdCd=CPFM.FeeMatrixProdCd AND CICF.SubProdCd=CPFM.FeeMatrixSubProdCd AND CICF.FeeTypCd=CPFM.FeeTypCd
INNER JOIN tblContractProdFeeMatrixVersion(NOLOCK) CPFMV ON CPFM.ContractProdFeeMatrixVersionId=CPFMV.ContractProdFeeMatrixVersionId
INNER JOIN tblContractProdFee(NOLOCK) CP ON CICF.ContractProdID=CP.ContractProdId AND CICF.ContractSubProdID=CP.ContractSubProdId AND CICF.ContractProdFeeId=CP.ContractProdFeeId
AND CPFM.FeeDeterminantCd=CP.FeeDeterminantCd AND CPFM.RowMatrixParameterCd =CP.RowMatrixParameterCd
WHERE CICF.ContractId=#ContractId AND CPFMV.ProdFeeMatrixVerNo=#VersionNo AND CICF.ContractProdStatusCd=1 AND CICF.ContractSubProdStatusCd=1 AND CP.ContractProdFeeTypStatusCd=1
AND CPFM.RowMatrixParameterCd IN(6,4)
AND EXISTS(SELECT PFM.ContractProdFeeId from tblProdFeeMatrix(NOLOCK)PFM WHERE CICF.ContractProdFeeId=PFM.ContractProdFeeId)
IF EXISTS(Select 1 From #tblContractInterCulturalDataFilteredUpdate(NOLOCK))
BEGIN
DELETE PFM
FROM tblProdFeeMatrix(NOLOCK) PFM
INNER JOIN #tblContractInterCulturalDataFilteredUpdate(NOLOCK) TIFU ON TIFU.ContractProdFeeId=PFM.ContractProdFeeId
END
INSERT INTO #tblContractInterCulturalDataFilteredInsert(
ContractID
, ContractProdID
, ProdCd
, ProdName
, ContractSubProdID
, SubProdCd
, SubProdName
, ContractProdStatusCd
, ContractProdStatusDt
, ContractSubProdStatusCd
, ContractSubProdStatusDt
, FeeTypCd
, FeeDeterminantCd
, RowMatrixParameterCd
, ProdFeeCurrCd
, RowParameterValueCd
, ColumnParameterValueCd
, ProdFeePct
, RangeFromDayCnt
, RangeToDayCnt
, ProdFeeLevelMinAmt
, ProdFeeLevelMaxAmt
, ProdFeeAmt
, ContractProdFeeId
, CreatedDate
)
SELECT DISTINCT CICF.ContractId,
CICF.ContractProdId,
CICF.ProdCd,
CICF.ProdName,
CICF.ContractSubProdID,
CICF.SubProdCd,
CICF.SubProdName,
CICF.ContractProdStatusCd,
CICF.ContractProdStatusDt,
CICF.ContractSubProdStatusCd,
CICF.ContractSubProdStatusDt,
CPFM.FeeTypCd,
CPFM.FeeDeterminantCd,
CPFM.RowMatrixParameterCd,
CPFM.ProdFeeCurrCd,
CPFM.RowParameterValueCd,
CPFM.ColumnParameterValueCd,
CPFM.ProdFeePct,
CPFM.RangeFromDayCnt,
CPFM.RangeToDayCnt,
CPFM.ProdFeeLevelMinAmt,
CPFM.ProdFeeLevelMaxAmt,
CPFM.ProdFeeAmt,
CICF.ContractProdFeeId,
Getdate()
FROM #tblContractInterCulturalDataFiltered(NOLOCK) CICF
INNER JOIN tblContractProdFeeMatrix(NOLOCK) CPFM ON CICF.ProdCd=CPFM.FeeMatrixProdCd AND CICF.SubProdCd=CPFM.FeeMatrixSubProdCd AND CICF.FeeTypCd=CPFM.FeeTypCd
INNER JOIN tblContractProdFeeMatrixVersion(NOLOCK) CPFMV ON CPFM.ContractProdFeeMatrixVersionId=CPFMV.ContractProdFeeMatrixVersionId
INNER JOIN tblContractProdFee(NOLOCK) CP ON CICF.ContractProdID=CP.ContractProdId AND CICF.ContractSubProdID=CP.ContractSubProdId AND CICF.ContractProdFeeId=CP.ContractProdFeeId
AND CPFM.FeeDeterminantCd=CP.FeeDeterminantCd AND CPFM.RowMatrixParameterCd =CP.RowMatrixParameterCd
WHERE CICF.ContractId=#ContractId AND CPFMV.ProdFeeMatrixVerNo=#VersionNo AND CICF.ContractProdStatusCd=1 AND CICF.ContractSubProdStatusCd=1 AND CP.ContractProdFeeTypStatusCd=1
AND CPFM.RowMatrixParameterCd IN(6,4)
IF EXISTS(Select 1 From #tblContractInterCulturalDataFilteredInsert(NOLOCK))
BEGIN
INSERT INTO [dbo].[tblProdFeeMatrix]
([ContractProdFeeId]
,[ContractBundleFeeId]
,[ContractProdBundleAncilFeeId]
,[RowParameterValueCd]
,[ColumnParameterValueCd]
,[ProdFeeAmt]
,[ProdFeeCurrCd]
,[ProdFeePct]
,[RangeFromDayCnt]
,[RangeToDayCnt]
,[RangeFromPct]
,[RangeToPct]
,[RangeFromAmt]
,[RangeToAmt]
,[ProdFeeLevelMinAmt]
,[ProdFeeLevelMaxAmt]
,[FeeNotApplyIndCd]
,[CreateId]
,[CreateDt]
,[UpdateId]
,[UpdateDt]
,[FunctionId])
SELECT DISTINCT
TIFI.ContractProdFeeID,
0,
0,
TIFI.RowParameterValueCd,
TIFI.ColumnParameterValueCd,
TIFI.ProdFeeAmt,
TIFI.ProdFeeCurrCd,
TIFI.ProdFeePct,
TIFI.RangeFromDayCnt,
TIFI.RangeToDayCnt,
0,
0,
0,
0,
TIFI.ProdFeeLevelMinAmt,
TIFI.ProdFeeLevelMaxAmt,
0,
#UserId,
GETDATE(),
#UserId,
GETDATE(),
#FunctionId
FROM #tblContractInterCulturalDataFilteredInsert(NOLOCK) TIFI
END
IF(#ConvRateFlag=1)
BEGIN
EXEC [ASSET_DB].[dbo].[prcCalculateRates] #UserId,#ContractId,#SelectAll,#SubProductList,#FeesOverrideFlg
END
COMMIT TRANSACTION
SELECT #RetVal=0
GOTO CLEARTEMPTABLES
GOTO DONE
END TRY
BEGIN CATCH
SELECT #ErrMsg = ERROR_PROCEDURE() + ': ' + ERROR_MESSAGE() + ' (Error No. ' + Ltrim(Str(ERROR_NUMBER())) + ') ' + ' at line # ' + Ltrim(Str(ERROR_LINE()))
,#RetVal = 200
GOTO CLEARTEMPTABLES
GOTO ERROR
END CATCH
ERROR:
ROLLBACK TRANSACTION
RAISERROR(#ErrMsg,16,1 )
CLEARTEMPTABLES:
BEGIN TRY
IF EXISTS ( SELECT * FROM tempdb..sysobjects WHERE id = object_id(N'[tempdb]..[#tblMasterData]') )
BEGIN
TRUNCATE TABLE #tblMasterData
DROP TABLE #tblMasterData
END
IF EXISTS ( SELECT * FROM tempdb..sysobjects WHERE id = object_id(N'[tempdb]..[#tblContractInterCulturalDataFiltered]') )
BEGIN
TRUNCATE TABLE #tblContractInterCulturalDataFiltered
DROP TABLE #tblContractInterCulturalDataFiltered
END
IF EXISTS ( SELECT * FROM tempdb..sysobjects WHERE id = object_id(N'[tempdb]..[#tblContractInterCulturalDataFilteredInsert]') )
BEGIN
TRUNCATE TABLE #tblContractInterCulturalDataFilteredInsert
DROP TABLE #tblContractInterCulturalDataFilteredInsert
END
IF EXISTS ( SELECT * FROM tempdb..sysobjects WHERE id = object_id(N'[tempdb]..[#tblContractInterCulturalDataFilteredUpdate]') )
BEGIN
TRUNCATE TABLE #tblContractInterCulturalDataFilteredUpdate
DROP TABLE #tblContractInterCulturalDataFilteredUpdate
END
IF EXISTS ( SELECT * FROM tempdb..sysobjects WHERE id = object_id(N'[tempdb]..[#tblSelContractSubProds]') )
BEGIN
TRUNCATE TABLE #tblSelContractSubProds
DROP TABLE #tblSelContractSubProds
END
END TRY
BEGIN CATCH
SELECT #ErrMsg = ERROR_PROCEDURE() + ': ' + ERROR_MESSAGE() + ' (Error No. ' + Ltrim(Str(ERROR_NUMBER())) + ') ' + ' at line # ' + Ltrim(Str(ERROR_LINE()))
,#RetVal = 201
GOTO ERROR
END CATCH
DONE:
SET NOCOUNT OFF
Return (#RetVal)
END
The fact that lead to this error is that the BEGIN TRANSACTION executed, but neither COMMIT or ROLLBACK did.
The usual reason a stored procedure with a try-transaction block returns that message is the error: table (or other object) not found. This is NOT caught in the try-catch block.
Check the object names exist on runtime.
Also, make sure to run a ROLLBACK manually on the session that spawned this message, if you still haven't fixed the proc.
Documentation:
The following types of errors are not handled by a CATCH block when
they occur at the same level of execution as the TRY...CATCH
construct:
(........)
Object name resolution errors
As you can see, there are also other errors not caught which may be the problem. Check out the possibilities. Many of these error, including the object name resolution, can be caught if you put the procedure CALL inside a try-catch block.
begin try
exec [dbo].[prcInsDataFeesForVersion] ..............
end try
begin catch
SELECT #ErrMsg = ERROR_PROCEDURE() + ': ' + ERROR_MESSAGE() + ' (Error No. ' + Ltrim(Str(ERROR_NUMBER())) + ') ' + ' at line # ' + Ltrim(Str(ERROR_LINE()))
,#RetVal = 201
end catch
This might not sound handy, but at least you can use it to find the error out.

SQL XMLNS failing with sp_executesql sproc

I have the following:
DECLARE #csXml XML
, #changeStatus XML
, #tNum NVARCHAR(25) = '0001aa17'
SELECT #csXml = ChangeSet
FROM [Issues]
WHERE [TrackingNumber] = #tNum
SET #changeStatus =
(
SELECT NEWID() AS [#id]
, 'me#sample.com' AS [#by]
, '1E910737-D78C-E711-9C04-00090FFE0001' AS [#byAccountId]
, '2018-01-18T18:39:03.220Z' AS [#when]
, 'Status' AS [property/#id]
, 'Status' AS [property/#name]
, 'In Review' AS [property/#old]
, 'Closed' AS [property/#new]
, '' AS [collections]
FOR XML PATH('change')
);
-- Add node to XML...
SET #csXml.modify(N'declare default element namespace "http://www.sample.com/ChangeSet/2017/09";
insert sql:variable("#changeStatus") as last into (/changes)[1]');
SET #ParamDef = N'#TrackingNumber NVARCHAR(25)
, #ChangeSet XML';
SET #sql = 'EXEC [SaveIssue] #TrackingNumber, #ChangeSet';
EXEC [sys].[sp_executesql] #sql
, #paramDef
, #TrackingNumber = #tNum
, #ChangeSet = #csXml;
I am getting back an error of:
Msg 6965, Level 16, State 1, Procedure SaveIssue, Line 27 XML
Validation: Invalid content. Expected element(s):
'{http://www.sample.com/ChangeSet/2017/09}change'. Found: element
'change' instead. Location: /:changes[1]/:change[4].
I understand that the sproc I am calling is throwing this error. What I cannot figure out is how to correctly call this sproc to make it stop! :)
The (truncated) definition for the sproc is:
CREATE PROCEDURE [SaveIssue]
( #TrackingNumber NVARCHAR(25)
, #ChangeSet XML(DOCUMENT Reference.sample) = N'<changes xmlns="http://www.sample.com/ChangeSet/2017/09" />'
)
AS
BEGIN
...
END
I have tried tying the XMLNS definition to the XML declaration(s), casting the final #csXml to XML and back to XML(DOCUMENT ...), etc. Nothing I am so far trying is working. I also tried a WITH XMLNAMESPACE... for the #changeStatus SELECT. I am a bit stumped!
Using a CTE solved this for me. First, I had to change the SET to a SELECT. Then added the WITH XMLNAMESPACE... portion. Here is the corrected piece to create the node I want to insert:
;WITH XMLNAMESPACES (DEFAULT 'http://www.sample.com/ChangeSet/2017/09')
SELECT #changeStatus =
(
SELECT NEWID() AS [#id]
, 'me#sample.com' AS [#by]
, '1E910737-D78C-E711-9C04-00090FFE0001' AS [#byAccountId]
, '2018-01-18T18:39:03.220Z' AS [#when]
, 'Status' AS [property/#id]
, 'Status' AS [property/#name]
, 'In Review' AS [property/#old]
, 'Closed' AS [property/#new]
, '' AS [collections]
FOR XML PATH('change')
);

Capture multiple rows in the last single insert action and select from them without using triggers?

I have the following insert action :
declare #appName varchar(35), #modName varchar(125), #cnt int;
select #cnt=0;
BEGIN TRY
insert into dbo.AppsMonitor (
AppName, AppLoadTime, AppLastUpdate, ModName, ModLoadTime, ModLastUpdate , ModErrMsg
)
SELECT
_Scanner.value('#scannerName' , 'varchar(25)') AS scannerName
, _Scanner.value('#StartAt' , 'varchar(22)') AS LoadTime
, _Scanner.value('#LastUpdate' , 'varchar(22)') AS LastUpdate
, _Module.value('#modName' , 'varchar(125)') AS ModName
, _Module.value('#StartAt' , 'varchar(22)') AS LoadTime
, _Module.value('#LastUpdate' , 'varchar(22)') AS LastUpdate
, _Module.value('ErrMsg[1]' , 'varchar(500)') AS ErrMsg
FROM #xml.nodes('/AllMyScanners/Scanners/Scanner')
As AllMyScanners(_Scanner)
CROSS APPLY _Scanner.nodes('Modules/Module')
AS Modules(_Module)
select #cnt=##ROWCOUNT
END TRY
BEGIN CATCH
set #rr=-2;
print 'Err#4'
END CATCH
I want to select some fields from the inserted buffer (something like ##inserted) what I have just inserted into the table dbo.AppsMonitor for analytical purpose.
How to do that without using triggers? My team does not allow triggers!
You can do that with an OUTPUT Clause. Use OUTPUT INSERTED.xxx
Thankyou Amit for your answer. TO make it more clear for other readers, my code using OUTPUT for INSERTED is
BEGIN TRY
insert into dbo.AppsMonitor (
AppName, AppLoadTime, AppLastUpdate, ModName, ModLoadTime, ModLastUpdate , ModErrMsg
)
OUTPUT INSERTED.AppName, INSERTED.ModName into #tmpVar
SELECT
_Scanner.value('#scannerName' , 'varchar(25)') AS scannerName
, _Scanner.value('#StartAt' , 'varchar(22)') AS LoadTime
, _Scanner.value('#LastUpdate' , 'varchar(22)') AS LastUpdate
, _Module.value('#modName' , 'varchar(125)') AS ModName
, _Module.value('#StartAt' , 'varchar(22)') AS LoadTime
, _Module.value('#LastUpdate' , 'varchar(22)') AS LastUpdate
, _Module.value('ErrMsg[1]' , 'varchar(500)') AS ErrMsg
FROM #xml.nodes('/AllMyScanners/Scanners/Scanner')
As AllMyScanners(_Scanner)
CROSS APPLY _Scanner.nodes('Modules/Module')
AS Modules(_Module)
select #cnt=##ROWCOUNT
END TRY
BEGIN CATCH
set #rr=-2;
print 'Err#4'
END CATCH

Inserting records in temporary table in sql server?

In SQL Server, I declare one table and trying to insert records, but it is taking so much time to insert. This is my temp table :
declare #totalAprovals Table(
apptype varchar(max)
, Id varchar(max)
, empno varchar(max)
, empname varchar(max)
, AppliedDate varchar(max)
, rstatus varchar(max)
, LeaveType varchar(max)
, fromdate varchar(max)
, todate varchar(max)
, finyear varchar(max)
, noofdays varchar(max)
, perdate varchar(max)
, pertype varchar(max)
, TotMin varchar(max)
, FrmTime varchar(max)
, ToTime varchar(max)
, ConDate varchar(max)
, Amount varchar(max)
, MaterialDesc varchar(max)
, EstValue varchar(max)
, FromYear varchar(max)
, ToYear varchar(max)
, AvailedFrom varchar(max)
, AvailedTo varchar(max)
, Purpose varchar(max)
, FromPlace varchar(max)
, ToPlace varchar(max)
, ICode varchar(max)
, IDesc varchar(max)
, MgrId varchar(max)
)
and my insert statement :
insert into #totalAprovals
SELECT DISTINCT 'LEAVE' AppType
, CRS.applicationId ID
, CRS.EmpId EmpNo
, ISNULL((
SELECT FirstName
FROM Tbl_Emp_M
WHERE EmpId=CRS.EmpId
)
, CRS.EmpId) EmpName
, CONVERT(VARCHAR(10),LA.LeaveDate,103) AppliedDate
, (CASE ISNULL((
SELECT top 1 CurStatus
FROM Tbl_CRS_Leave_AppHis_T
WHERE stepno=CRS.StepNo-1
and applicationId=CRS.applicationId
AND Status=1
order by StepNo desc),'0')
WHEN '0' THEN 'Applied'
WHEN '1' THEN 'Recommended'
WHEN '2' THEN 'Approved'
END) Rstatus
, LT.LeaveName LeaveType
, CONVERT(VARCHAR(10),LA.FromDate,103) FromDate
, CONVERT(VARCHAR(10),LA.ToDate,103) ToDate
, '' FinYear
, '' NoOfDays
, '' PerDate
, '' PerType
, '' TotMin
, '' FrmTime
, '' ToTime
, '' ConDate
, 0 Amount
, '' MaterialDesc
, 0 EstValue
, '' FromYear
, '' ToYear
, ''AvailedFrom
, '' AvailedTo
, '' Purpose
, '' FromPlace
, '' ToPlace
, '' ICode
, '' IDesc
, CRS.MgrId
FROM Tbl_Leave_App_T LA
, Tbl_CRS_Leave_App_T CRS
, Tbl_Leave_Typ_M LT
, Tbl_Emp_ServiceDetails_T EMS
WHERE CRS.applicationId = LA.ApplicationId
AND LA.LeaveTypeId = LT.LeaveTypeId
and crs.EmpId = ems.EmpId
AND CRS.Status = 1
AND LA.Status = 1
AND LT.Status = 1
and ems.Status = 1
AND CRS.CurStatus IN ('0')
AND YEAR(LA.LeaveDate) = YEAR(GETDATE())
AND la.LeaveTypeId not in (9,12)
AND -- LA.ApplicationId LIKE '%LEV%' AND
CRS.EmpId = EMS.EmpId
and ems.LocationCode IN ('101','102','103','104','AHUP')
and crs.MgrId ='xxxxx'
It is taking 2 to 3 minutes to execute this. What could be the reason? Am I writing wrong process to insert records?
You have a performance problem so investigate it as a performance problem. Use a methodology like Waits and Queues. Follow the SQL Server PErformance Flowchart.
When you post here, always add the exact DDL used to create those tables, including all indexes, and capture and link the execution plans.
Most likely is not the INSERT the problem, but the SELECT. DISTINCT is always a code smell indicating a poorly understood join. The WHERE clause is full of non-sargable predicates.
I got the solution, actually i replace the declaring the table like
"declare #totalAprovals Table" to "create table #totalAprovals now it is working superb. Thank you for replying all.

Delete and insert on same procedure

In my SQL stored procedure, I need to delete and insert on same query. My syntax is below. But my syntax fails to store data. Why does it fail? How do I solve this problem? My syntax is
CREATE PROCEDURE spInsertCollectionInspectionHours
#StartDate DATETIME ,
#EndDate DATETIME ,
#ID BIGINT ,
#VesselName VARCHAR(80) ,
#VoyageNo VARCHAR(15) ,
#PortCode VARCHAR(20) ,
#Terminal VARCHAR(70) ,
#InspectionDate DATETIME ,
#InvoiceHours INT ,
#ManifestType INT ,
#Remarks NVARCHAR(200)
AS
BEGIN
BEGIN
DELETE FROM dbo.InspectionHours
WHERE InspectionDate BETWEEN #StartDate AND #EndDate
END
BEGIN
SELECT #ID = ISNULL(MAX(ID), 0) + 1
FROM [InspectionHours]
INSERT INTO [InspectionHours]
( [ID] ,
[VesselName] ,
[VoyageNo] ,
[PortCode] ,
[Terminal] ,
[InspectionDate] ,
[InvoiceHours] ,
[ManifestType] ,
[Remarks]
)
VALUES ( #ID ,
#VesselName ,
#VoyageNo ,
#PortCode ,
#Terminal ,
#InspectionDate ,
#InvoiceHours ,
#ManifestType ,
#Remarks
)
END
END
If have any questions please ask. Thanks in advance.
check your id field identity property is true or not if it's true or yes then no need to give id in insert statement
Your syntax is fine. This should not produce and error.
Your insert statement is also fine. If it is not throwing an error then something else is going on. Are you sure you are passing parameters? Are you sure you are looking in the correct server/db/table and using the correct query to check? Are you positive it's not throwing an error?