SQL Server: Nested cursor syntax error - sql-server

I tried to define following SQL Server nested cursor statement: I loop calendars and migrate them from cut_calendar to sd_calendar. Each calendar also have calendar days. They are also moved by each calendar move.
DECLARE #id NUMERIC(20)
DECLARE #sdCalendarId NUMERIC(20)
DECLARE #calendarTypId NUMERIC(5)
DECLARE #name NVARCHAR(35)
DECLARE #description NVARCHAR(255)
DECLARE #ptyId NUMERIC(20)
DECLARE #lockCode NVARCHAR(20)
DECLARE #dataOwnerId NUMERIC(20)
DECLARE #cntId NUMERIC(20)
DECLARE #nonBusinessDaysMonday CHAR(1)
DECLARE #nonBusinessDaysTuesday CHAR(1)
DECLARE #nonBusinessDaysWednesday CHAR(1)
DECLARE #nonBusinessDaysThursday CHAR(1)
DECLARE #nonBusinessDaysFriday CHAR(1)
DECLARE #nonBusinessDaysSaturday CHAR(1)
DECLARE #nonBusinessDaysSunday CHAR(1)
DECLARE #ccyId NUMERIC(20)
DECLARE #code NVARCHAR(30)
DECLARE #version NUMERIC(10)
DECLARE #seal VARCHAR(255)
DECLARE #lstUpdTs DATETIME
DECLARE #day_id NUMERIC(20)
DECLARE #day_calDate DATETIME
DECLARE #day_lockCode NVARCHAR(20)
DECLARE #day_calComment NVARCHAR(255)
DECLARE #day_dataOwnerId NUMERIC(20)
DECLARE #day_calendarId NUMERIC(20)
DECLARE #day_calRecurring CHAR(1)
DECLARE #day_version NUMERIC(10)
DECLARE #day_seal VARCHAR(255)
DECLARE #day_lstUpdTs DATETIME
DECLARE #day_sdCalendarDaysId NUMERIC(20)
DECLARE #sdCodeId NUMERIC(20)
DECLARE cursorCutoffCalendar CURSOR FOR
SELECT ID, NAME, CALENDAR_TYP_ID,DESCRIPTION,PTY_ID,LOCK_CODE,DATA_OWNER_ID,CNT_ID,NON_BUSINESS_DAYS_MONDAY,NON_BUSINESS_DAYS_TUESDAY,NON_BUSINESS_DAYS_WEDNESDAY,NON_BUSINESS_DAYS_THURSDAY,NON_BUSINESS_DAYS_FRIDAY,NON_BUSINESS_DAYS_SATURDAY,NON_BUSINESS_DAYS_SUNDAY,CCY_ID,CODE,VERSION,SEAL,LST_UPD_TS
FROM CUT_CALENDAR
WHERE ID != 1
OPEN cursorCutoffCalendar
FETCH NEXT FROM cursorCutoffCalendar INTO #id, #name, #calendarTypId, #description, #ptyId, #lockCode, #dataOwnerId, #cntId, #nonBusinessDaysMonday, #nonBusinessDaysTuesday, #nonBusinessDaysWednesday, #nonBusinessDaysThursday, #nonBusinessDaysFriday, #nonBusinessDaysSaturday, #nonBusinessDaysSunday, #ccyId, #code, #version, #seal, #lstUpdTs
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #sdCalendarId = COALESCE(MAX(ID),1) FROM SD_CALENDAR
SET #sdCalendarId = #sdCalendarId + 1
UPDATE CUT_CALENDAR_DAY
SET CALENDAR_ID = #sdCalendarId
WHERE CALENDAR_ID = #id
SELECT #sdCodeId = ID FROM SD_CALENDAR WHERE CODE = #code
IF #sdCodeId > 0
SET #code = CONCAT(#code, '_co')
ELSE
INSERT INTO SD_CALENDAR (ID, NAME, CALENDAR_ROLE_ID,DESCRIPTION,USE_IN_CUTOFF,PTY_ID,LOCK_CODE,DATA_OWNER_ID,CNT_ID,NON_BUSINESS_DAYS_MONDAY,NON_BUSINESS_DAYS_TUESDAY,NON_BUSINESS_DAYS_WEDNESDAY,NON_BUSINESS_DAYS_THURSDAY,NON_BUSINESS_DAYS_FRIDAY,NON_BUSINESS_DAYS_SATURDAY,NON_BUSINESS_DAYS_SUNDAY,CCY_ID,CODE,VERSION,SEAL,LST_UPD_TS)
VALUES(#sdCalendarId, #name, #calendarTypId,#description,1,#ptyId,#lockCode,#dataOwnerId,#cntId,#nonBusinessDaysMonday,#nonBusinessDaysTuesday,#nonBusinessDaysWednesday,#nonBusinessDaysThursday,#nonBusinessDaysFriday,#nonBusinessDaysSaturday,#nonBusinessDaysSunday,#ccyId,#code,#version,#seal,#lstUpdTs)
DECLARE cursorCutoffCalendarDays CURSOR FOR
SELECT ID, CAL_DATE, LOCK_CODE,CAL_COMMENT,DATA_OWNER_ID,CALENDAR_ID,CAL_RECURRING,VERSION,SEAL,LST_UPD_TS
FROM CUT_CALENDAR_DAY
WHERE ID != 1
OPEN cursorCutoffCalendarDays
FETCH NEXT FROM cursorCutoffCalendarDays INTO #day_id, #day_calDate, #day_lockCode, #day_calComment, #day_dataOwnerId, #day_calendarId, #day_calRecurring, #day_version, #day_seal, #day_lstUpdTs
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #day_sdCalendarDaysId = COALESCE(MAX(ID),1) FROM SD_CALENDAR_DAY
SET #day_sdCalendarDaysId = #day_sdCalendarDaysId + 1
INSERT INTO SD_CALENDAR_DAY (ID, CAL_DATE, LOCK_CODE,CAL_COMMENT,DATA_OWNER_ID,CALENDAR_ID,CAL_RECURRING,VERSION,SEAL,LST_UPD_TS)
VALUES(#day_sdCalendarDaysId, #day_calDate, #day_lockCode, #day_calComment, #day_dataOwnerId, #day_calendarId, #day_calRecurring, #day_version, #day_seal, #day_lstUpdTs)
FETCH NEXT FROM cursorCutoffCalendarDays INTO #day_sdCalendarDaysId, #day_calDate, #day_lockCode, #day_calComment, #day_dataOwnerId, #day_calendarId, #day_calRecurring, #day_version, #day_seal, #day_lstUpdTs
END
CLOSE cursorCutoffCalendarDays
DEALLOCATE cursorCutoffCalendarDays
GO
DELETE FROM CUT_CALENDAR
WHERE ID = #id
FETCH NEXT FROM cursorCutoffCalendar INTO #sdCalendarId, #name, #calendarTypId, #description, #ptyId, #lockCode, #dataOwnerId, #cntId, #nonBusinessDaysMonday, #nonBusinessDaysTuesday, #nonBusinessDaysWednesday, #nonBusinessDaysThursday, #nonBusinessDaysFriday, #nonBusinessDaysSaturday, #nonBusinessDaysSunday, #ccyId, #code, #version, #seal, #lstUpdTs
END
CLOSE cursorCutoffCalendar
DEALLOCATE cursorCutoffCalendar
GO
Now when I run this, I get following error:
SQLServerException: Incorrect syntax near 'cursorCutoffCalendarDays'.
cursorCutoffCalendarDays is the inner cursor of my statement.

Try removing GO from:
CLOSE cursorCutoffCalendarDays
DEALLOCATE cursorCutoffCalendarDays
GO
And I agree with the comment you got from GarethD, I used to write cursors like this but then I asked how to do it without the cursor and got a nice explanation

Blockquote
Remove Go from this line then try
CLOSE cursorCutoffCalendarDays
DEALLOCATE cursorCutoffCalendarDays

Related

Have anyone a solution to send row parameter to a stored prodedure in MS-SQL Server with dynamic Column Arrangement?

I Could write a trigger for a table that is able to detect updated columns and logs the changes. I want to make a stored procedure from this trigger and call it when required. But I do not know how can I send "inserted" or "updated" rows that are valid in trigger body, to this SP.
Here is my trigger :
CREATE TRIGGER [dbo].[tgr_MyTable_TransactionLogUpdate]
ON [dbo].[MyTable]
AFTER UPDATE
AS
BEGIN
if (select F_SharhRadif from [Payeh.Decode] where F_ShJadval=18 and F_ShRadif=1)='2'
begin
return
end
declare #userid int=(select top 1 userid from inserted)
declare #computername nvarchar(50)=(select top 1 computername from inserted)
declare #ip nvarchar(50)=(select top 1 IP from inserted)
declare #zamantaqeer datetime=(select top 1 F_ZamanTaqeer from inserted)
declare #changetime =GETDATE()
DECLARE #tableID BIGINT=(SELECT id FROM sys.sysobjects WHERE [name]='MyTable')
DECLARE #ColCount INT=(SELECT COUNT(*) FROM sys.syscolumns WHERE id=#tableID)
DECLARE #ColIndex INT=1
DECLARE #UpdateDetails NVARCHAR(MAX)=''
DECLARE #ColName NVARCHAR(1000)
DECLARE #ByteIndex INT
SELECT * INTO #d FROM deleted
SELECT * INTO #i FROM inserted
WHILE (#ColIndex<=#ColCount)
BEGIN
--IF (COLUMNS_UPDATED()&POWER(2,#ColIndex-1) <> 0)
SET #ByteIndex=((#ColIndex-1)/8)+1
IF (CONVERT(INT,SUBSTRING(COLUMNS_UPDATED(),#ByteIndex,1))&POWER(2,((#ColIndex-1)%8)) <> 0)
BEGIN
SET #ColName=(SELECT [name] FROM sys.syscolumns WHERE id=#tableID AND colid=#ColIndex)
DECLARE #OldValue NVARCHAR(MAX)
DECLARE #NewValue NVARCHAR(MAX)
DECLARE #ParmDefinition NVARCHAR(100)=N'#DeletedValue NVARCHAR(MAX) OUTPUT'
DECLARE #SQL NVARCHAR(1000)='SELECT #DeletedValue=LTRIM(RTRIM(CONVERT(nvarchar(MAX),'+#ColName+'))) FROM #d'
EXEC sp_executesql #SQL,#ParmDefinition,#DeletedValue=#OldValue OUTPUT
SET #ParmDefinition = N'#InsertedValue NVARCHAR(MAX) OUTPUT'
SET #SQL= 'SELECT #InsertedValue=LTRIM(RTRIM(CONVERT(nvarchar(MAX),'+#ColName+'))) FROM #i'
EXEC sp_executesql #SQL,#ParmDefinition,#InsertedValue=#NewValue OUTPUT
IF (#OldValue<>#NewValue)
BEGIN
SET #UpdateDetails=#UpdateDetails+#ColName+': OLD="'+ #OldValue+'" -New="'+#NewValue+'", '
END
END
SET #ColIndex=#ColIndex+1
END
IF (LEN(#UpdateDetails)>0)
BEGIN
SET #UpdateDetails=SUBSTRING(#UpdateDetails,1,LEN(#UpdateDetails)-1)
END
ELSE
BEGIN
SET #UpdateDetails='No Changes'
END
--[User.TransactionLog] is the name of the table that stores the history of changes
INSERT INTO [User.TransactionLog]
([Tablename],[OperationType],[Desciption],[UserID],[ComputerName],[IP],[ChangeTime])
SELECT 'MyTable',2,#UpdateDetails,'',#userid,#computername,#ip, #changetime
DROP TABLE #d
DROP TABLE #i

T-SQL 2008- Exit when Value is NULL

I am looking for a way to exit an T-SQL script when #Value is null. This is what I have so far but it does not work as expected:
SELECT
#Value,
CASE
WHEN #Value IS NULL
RAISERROR('EXIT', 16, 1)
FROM
table
WHERE
name LIKE 'test'
Perhaps this will work for you:
DECLARE #Value INT = 1
IF( #Value IS NULL)
BEGIN
RAISERROR('Exit',16,1)
END
ELSE
BEGIN
SELECT #Value
END
IF #Value IS NULL RAISERROR('EXIT', 16,1);
Using a cursor and a temp table you can get the output you want. don't know if that's the goal,
USE AdventureWorksLT2012
DECLARE #CustomerID AS INT
DECLARE #CompanyName AS VARCHAR(MAX)
DECLARE #EmailAddress AS VARCHAR(MAX)
CREATE TABLE #output (CustomerID INT,CompanyName VARCHAR(MAX),EmailAddress VARCHAR(MAX))
DECLARE testCursor CURSOR
FOR
SELECT TOP (100)
CustomerID
,CompanyName
,EmailAddress
FROM SalesLT.Customer
ORDER BY customerID DESC;
OPEN testCursor;
FETCH NEXT FROM testCursor
INTO #CustomerID, #CompanyName, #emailAddress;
if #EmailAddress is not null
BEGIN
INSERT INTO #output values( #CustomerID, #CompanyName, #emailAddress);
WHILE ##FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM testCursor
INTO #CustomerID, #CompanyName, #emailAddress;
if #EmailAddress is null
BEGIN
RAISERROR('Exit',16,1);
BREAK;
end
INSERT INTO #output values( #CustomerID, #CompanyName, #emailAddress);
END;
END
CLOSE testCursor;
DEALLOCATE testCursor;
SELECT * FROM #output;
DROP TABLE #output

Storing output of a stored procedure into a variable when the stored procedure is called with in another stored procedure

I am executing a stored procedure within another stored procedure and then want to store the result of the inner stored procedure into a variable to use it later. The result of the inner stored procedure will be a varchar value. How can I set a variable to the result of a stored procedure ?
ALTER PROCEDURE [dbo].[mvc_Formulas]
#Fund_ID nvarchar(max),
#Start_Dated datetime,
#End_Dated datetime
AS
DECLARE #FormulaType int
DECLARE #XFund_ID bigint
DECLARE #ReturningTable TABLE(fundname varchar(100), zRETURN nvarchar(100))
DECLARE #zRETURN nvarchar(100)
DECLARE #zSD nvarchar(100)
DECLARE #FUNDS TABLE(FundId BIGINT)
INSERT INTO #FUNDS
SELECT item
FROM dbo.SplitString(#Fund_ID, ',')
DECLARE #MyCursor CURSOR;
DECLARE #CurFund BIGINT;
DECLARE #FundName NVARCHAR(100);
BEGIN
SET #MyCursor = CURSOR FOR
SELECT FundId FROM #FUNDS
OPEN #MyCursor
FETCH NEXT FROM #MyCursor INTO #CurFund
WHILE ##FETCH_STATUS = 0
BEGIN
SET #FundName = (SELECT FundName FROM FUNDS WHERE Fund_ID = #CurFund)
--inner SP--------------------------------------
SET #zRETURN = EXEC [dbo].[Fund_Performance_Graph] #Start_Dated, #End_Dated, #CurFund
-----------------------------------------------------
INSERT INTO #ReturningTable
SELECT #FundName, #zReturn
FETCH NEXT FROM #MyCursor INTO #CurFund
END
SELECT * FROM #ReturningTable
END
ALTER PROCEDURE [dbo].[mvc_Formulas]
#Fund_ID nvarchar(max),
#Start_Dated datetime,
#End_Dated datetime,
#Result varchar(1000) OUTPUT

When I execute the stored procedure I get an error

When I execute the stored procedure, I get this error:
Msg 8114, Level 16, State 5, Procedure SPXML, Line 158
Error converting data type varchar to numeric.
I'm using a stored procedure and cursor for the first time.
This is my stored procedure:
CREATE PROCEDURE [dbo].[SPXML]
(#CounterStockMaster text,
#CounterStockDetails text,
#CounterStock text)
AS
DECLARE #M0 VARCHAR(100) --EditStatus
DECLARE #M1 VARCHAR(100) --Counter_Code
DECLARE #M2 VARCHAR(100) --Counter_Name
DECLARE #M3 VARCHAR(100) --To Branch_Code
DECLARE #D1 VARCHAR(100) --Project Type
DECLARE #D2 VARCHAR(100) --drpC.Text
DECLARE #D3 VARCHAR(100) --grdGO.Rows[i].Cells["1"].Value
DECLARE #D4 VARCHAR(100) --grdGO.Rows[i].Cells["2"].Value
DECLARE #D5 VARCHAR(100)
DECLARE #C1 VARCHAR(100) --Cnt Code
DECLARE #C2 VARCHAR(100) --Item
DECLARE #C3 VARCHAR(100) --Qty
BEGIN
DECLARE #CNTNo VARCHAR(100)
DECLARE #idoc INT
DECLARE #INDate Datetime
DECLARE #Branch_Code NUMERIC(18,0)
DECLARE #ItemCode NUMERIC(18,0)
DECLARE #ItemQty NUMERIC(18,3)
DECLARE #PurRate NUMERIC(18,2)
DECLARE #SaleRate NUMERIC(18,2)
DECLARE #MRP NUMERIC(18,2)
DECLARE #PurDate DATETIME
DECLARE #Batch_No VARCHAR(50)
DECLARE #ExpiryDate DATETIME
DECLARE #MultiMRP BIT
BEGIN TRANSACTION
SET DATEFORMAT dmy
SET #MultiMRP = (Select ISNULL(Multiple_Mrp,0) from [Company])
EXEC sp_xml_preparedocument #idoc OUTPUT, #CounterStockMaster
DECLARE GINMasterCursor CURSOR FOR
SELECT * FROM OPENXML (#idoc, '/CSMASTER/ID',1)
WITH (M0 VARCHAR(100), M1 VARCHAR(100), M2 VARCHAR(100),M3 VARCHAR(100))
OPEN GINMasterCursor
FETCH NEXT FROM GINMasterCursor INTO #M0,#M1,#M2,#M3
IF #M0='T' ---Edit Mode TRUE
BEGIN --- Reversing the Item Stock for the Editing Sales START
SET #CNTNo = #M1
DECLARE GInDetailCursor CURSOR FOR
SELECT Counter_Stock_Code,Item_Code,Item_Qty,Branch_Code From [CntDetails]
WHERE Counter_Stock_Code = #CNTNo AND Branch_Code=#M3
OPEN GInDetailCursor
FETCH NEXT FROM GInDetailCursor INTO #CNTNo,#ItemCode,#ItemQty,#Branch_Code
WHILE ##FETCH_STATUS=0
BEGIN
IF #MultiMRP = 0
UPDATE [ITEM] SET ITEM_BAL = ITEM_BAL - #ItemQty , Transfer_flag=2, Ascend_flag=1 WHERE Item_Code = #ItemCode and Type_Code = 0 and Branch_Code = #M3
ELSE
UPDATE [ITEM] SET ITEM_BAL = ITEM_BAL - #ItemQty , Transfer_flag=2, Ascend_flag=1 WHERE Item_Code = #ItemCode and Item_MRP = #MRP and Type_Code = 0 and Branch_Code = #M3
FETCH NEXT FROM GInDetailCursor INTO #CNTNo,#ItemCode,#ItemQty,#Branch_Code
END
CLOSE GInDetailCursor
DEALLOCATE GInDetailCursor
END --- Reversing the Item Stock for the Editing GO END
ELSE
BEGIN
SET #CNTNo = (SELECT ISNULL(MAX(Counter_Stock_Code)+1,1) FROM [Counter Stock Master] where Branch_Code = #M3)
END
INSERT INTO [CntMaster]
(Counter_Stock_Code,Counter_Stock_Date,Branch_Code)
VALUES
(#CNTNo, #INDate, #M3)
CLOSE GINMasterCursor
DEALLOCATE GINMasterCursor
EXEC sp_xml_removedocument #idoc
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument #idoc OUTPUT, #CounterStockDetails
-- Execute a SELECT statement using OPENXML rowset provider.
DECLARE GInDetailsCursor CURSOR FOR
SELECT * FROM OPENXML (#idoc, '/CSDETAILS/ID',1)
WITH ( D1 VARCHAR(100), D2 VARCHAR(100), D3 VARCHAR(100), D4 VARCHAR(100))
OPEN GInDetailsCursor
FETCH NEXT FROM GInDetailsCursor INTO #D1,#D2,#D3,#D4
WHILE ##FETCH_STATUS = 0
BEGIN
IF #D1='A' or #D1='D' --For ProjectType ==> Departmental Stores
BEGIN
SET #D2 = #CNTNo
INSERT INTO [CntDetails]
(Counter_Stock_Code,Item_Code,Item_Qty,Branch_Code)
VALUES
(#D2, #D3, #D4, #M3)
IF #MultiMRP = 0
UPDATE [ITEM] SET ITEM_BAL = ITEM_BAL + #D4 , Transfer_flag=2, Ascend_flag=1 WHERE Item_Code = #D3 and Type_Code = 0 and Branch_Code = #M3
ELSE
UPDATE [ITEM] SET ITEM_BAL = ITEM_BAL + #D4 , Transfer_flag=2, Ascend_flag=1 WHERE Item_Code = #D3 and Type_Code = 0 and Branch_Code = #M3
END
FETCH NEXT FROM GInDetailsCursor INTO #D1,#D2,#D3,#D4
END
CLOSE GInDetailsCursor
DEALLOCATE GInDetailsCursor
***[EXEC sp_xml_removedocument #idoc ----------------------- "I get this error from this line"][1]***
-- Create an internal representation of the XML document.
EXEC sp_xml_preparedocument #idoc OUTPUT, #CounterStock
-- Execute a SELECT statement using OPENXML rowset provider.
DECLARE CSCursor CURSOR FOR
SELECT * FROM OPENXML (#idoc, '/CounterStock/ID',1)
WITH ( D1 VARCHAR(100), D2 VARCHAR(100), D3 VARCHAR(100), D4 VARCHAR(100))
OPEN CSCursor
FETCH NEXT FROM CSCursor INTO #D1,#D2,#D3,#D4
WHILE ##FETCH_STATUS = 0
BEGIN
IF #D1='A' or #D1='D' --For ProjectType ==> Departmental Stores
BEGIN
INSERT INTO [CntStock]
(Conter_Code,Item_Code,Item_Qty)
VALUES
(#D2, #D3, #D4)
IF #MultiMRP = 0
UPDATE [ITEM] SET ITEM_BAL = ITEM_BAL + #D4 , Transfer_flag=2, Ascend_flag=1 WHERE Item_Code = #D3 and Type_Code = 0 and Branch_Code = #M3
ELSE
UPDATE [ITEM] SET ITEM_BAL = ITEM_BAL + #D4 , Transfer_flag=2, Ascend_flag=1 WHERE Item_Code = #D3 and Type_Code = 0 and Branch_Code = #M3
END
FETCH NEXT FROM CSCursor INTO #D1,#D2,#D3,#D4
END
CLOSE CSCursor
DEALLOCATE CSCursor
EXEC sp_xml_removedocument #idoc
SELECT #CNTNo
COMMIT TRANSACTION
END
GO
I tried many times but i didn't solve this problem.
Does anyone have any suggestions?
Error here:
INSERT INTO [CntStock]
(Conter_Code,Item_Code,Item_Qty)
VALUES
(#D2, #D3, #D4) ---DECLARE #D4 VARCHAR(100) ---What is the type of 'Item_Qty' column in CntStock table,Is it numeric,You are assigning varchar to numberic field.
Try changing the type of #D4

Pass XML file as input parameter in stored procedure

Is it possible to pass an XML file as a parameter in a stored procedure in SQL Server?
I have tried this but it doesn't do what its supposed to:
DECLARE #XmlString2 as XML <--I have a feeling this is the problem
SET #XmlString2 = 'cast(x as XML)
from openrowset (bulk '''+#FileName+''', single_blob) as T(x)'
DECLARE cur CURSOR LOCAL for
SELECT
PA_ID = XTbl.value('(Answer_ID)[1]', 'varchar(400)'),
Question_ID = XTbl.value('(../../ID)[1]', 'bigint'),
QuestionText = XTbl.value('(../../QuestionText)[1]', 'varchar(200)'),
QuestionType = XTbl.value('(../../QuestionType)[1]','bigint'),
Questionaire_ID = XTbl.value('(../../QuestionaireID)[1]','bigint'),
Filter = XTbl.value('(../../Filter)[1]', 'bigint'),
Value = XTbl.value('(Value)[1]','varchar(400)'),
RequiresExplanation = XTbl.value('(RequiresExplanation)[1]','int'),
ReviewRequired = XTbl.value('(ReviewRequire)[1]','char(1)')
from #XmlString2.nodes('/Questions/Question/PossibleAnswers/PossibleAnswer') as XD(XTbl)
I have the same thing with a hardcoded address of the file and it works, so I was wondering if this is possible so as I can execute the stored procedure with a different file if I need to
Here's an example procedure that accepts XML as a string, and shreds it into tables. It's pretty gnarly to write this by hand, if you're doing many of these best to write some sort of generator based on your table definition.
The inputted xml is pretty simple, and attribute based
<xml>
<agent addr1='123 Main Street' city='Toronto' />
<agent addr1='123 Main Street' city='Toronto' />
</xml>
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[sp_INSERT_agents]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_INSERT_agents]
GO
CREATE PROCEDURE sp_INSERT_agents
#strXML ntext
AS
BEGIN
-- NOTE: This procedure was generated by WCG:ITX DB/XML mapping utility
-- Please do not update this code by hand.
DECLARE #RC int
DECLARE #iDoc int
DECLARE #dtcurrenttime datetime
SET #dtcurrenttime = CURRENT_TIMESTAMP
-- Field variables
DECLARE #addr1 varchar(50)
DECLARE #addr2 varchar(50)
DECLARE #agentid char(13)
DECLARE #city varchar(50)
DECLARE #email varchar(50)
DECLARE #fax varchar(25)
DECLARE #mobile varchar(25)
DECLARE #muli char(1)
DECLARE #name varchar(50)
DECLARE #notes varchar(500)
DECLARE #phone varchar(25)
DECLARE #state char(2)
DECLARE #zip varchar(10)
DECLARE #part char(1)
EXECUTE sp_xml_preparedocument #iDoc OUTPUT, #strXML
-- Create a temporary return table
create table #return
( err varchar(50), agentid char(13))
-- Set NOCOUNT ON, to allow data to be returned from the temporary table.
SET NOCOUNT ON
DECLARE #ElementCursor CURSOR
SET #ElementCursor = CURSOR SCROLL DYNAMIC FOR
SELECT addr1, addr2, agentid, city, email, fax, mobile, muli, name, notes, phone, state, zip, part FROM OPENXML( #iDoc, "//agent", 2 )
WITH( addr1 varchar(50) '#addr1', addr2 varchar(50) '#addr2', agentid char(13) '#dt', city varchar(50) '#city', email varchar(50) '#email', fax varchar(25) '#fax', mobile varchar(25) '#mobile', muli char(1) '#muli', name varchar(50) '#name', notes varchar(500) '#notes', phone varchar(25) '#phone', state char(2) '#state', zip varchar(10) '#zip', part char(1) '#part')
OPEN #ElementCursor
FETCH NEXT FROM #ElementCursor INTO #addr1, #addr2, #agentid, #city, #email, #fax, #mobile, #muli, #name, #notes, #phone, #state, #zip, #part
BEGIN TRANSACTION
WHILE ##FETCH_STATUS = 0
BEGIN
-- Convert any temp values to real date time values
BEGIN
INSERT into dbo.agents
(addr1, addr2, agentid, city, email, fax, mobile, muli, name, notes, phone, state, zip, part, dtmodified)
values
(#addr1, #addr2, #agentid, #city, #email, #fax, #mobile, #muli, #name, #notes, #phone, #state, #zip, #part, #dtcurrenttime)
END
-- Check for any errors on the insert / update
IF ##error <> 0
BEGIN
INSERT into #return
(err)
values
(##error)
END
FETCH NEXT FROM #ElementCursor INTO #addr1, #addr2, #agentid, #city, #email, #fax, #mobile, #muli, #name, #notes, #phone, #state, #zip, #part
END
COMMIT TRANSACTION
CLOSE #ElementCursor
DEALLOCATE #ElementCursor
EXECUTE sp_xml_removedocument #iDoc
-- Return the temporary data, containing any errors
SELECT * from #return
END
GO

Resources