我有一个存储过程,插入“人”。我有一个xml文档,其中包含一些我要插入的人。我想调用我的存储过程如下所示,并期望为xml中的每个人调用存储过程。它告诉我存储的proc“期望参数@Id”并且失败了。 @Id是第一个参数,似乎我的语法是不允许的。有没有办法在不迭代游标中的每个人的情况下执行此操作?我正在使用SQL Server 2005。
EXEC Stored_Procedure_That_Inserts_People
SELECT Node.value('Id[1]', 'Int') AS Id
,Node.value('FirstName[1]', 'varchar(50)') AS FirstName
,Node.value('LastName[1]', 'varchar(50)') AS LastName
,Node.value('MI[1]', 'char(1)') AS MI
FROM @PeopleXML.nodes('/ArrayOfPeople/Person') TempXML (Node)
对于任何感兴趣的人,这就是我根据Tom的答案实现我的解决方案的方式:
CREATE PROCEDURE [dbo].[ccIU_PersonBulkImport]
(
@PersonXML as xml
)
AS
BEGIN
SET NOCOUNT ON
DECLARE
@LastName AS varchar(50),
@FirstName AS varchar(50),
@MI AS char(1)
DECLARE People CURSOR FORWARD_ONLY STATIC READ_ONLY FOR
SELECT
Node.value('FirstName[1]', 'varchar(50)') AS FirstName
,Node.value('LastName[1]', 'varchar(50)') AS LastName
,Node.value('MI[1]', 'char(1)') AS MI
FROM @PersonXML.nodes('/ArrayOfPeople/Person') TempXML (Node)
OPEN People;
FETCH NEXT FROM People INTO @FirstName,@LastName,@MI
WHILE (@@FETCH_STATUS = 0)
BEGIN
EXEC domIU_People @FirstName,@LastName,@MI -- second stored proc that inserts or updates the person
FETCH NEXT FROM People INTO @FirstName,@LastName,@MI;
END
CLOSE People;
DEALLOCATE People;
END
答案 0 :(得分:2)
没有。
您无法迭代存储过程,因为通常它们只能将对象作为参数,异常是表对象。
在此示例中,SQL将尝试调用SP,然后将select作为单独的事件运行,这就是您收到有关缺少参数的错误的原因。
您的选择是遍历XML并为每条记录调用SP,重构SP以使用XML作为单独的参数工作,并在插入人员过程中将其分解或将sp中的代码重构为XML处理逻辑程序。
答案 1 :(得分:1)
如果存储过程是简单插入People表,那么您可以创建一个新的存储过程,例如:
CREATE PROCEDURE dbo.Insert_People_From_XML
@people_xml XML
AS
BEGIN
INSERT INTO dbo.People
(
id,
first_name,
last_name,
middle_initial
)
SELECT
Node.value('Id[1]', 'Int'),
Node.value('FirstName[1]', 'varchar(50)'),
Node.value('LastName[1]', 'varchar(50)'),
Node.value('MI[1]', 'char(1)')
FROM
@people_xml.nodes('/ArrayOfPeople/Person') TempXML (Node)
END
如果您有业务逻辑(或其他您不想复制的逻辑),那么您可能希望按原样重用插入存储过程。在这种情况下,您将不得不遍历XML节点。尽管我试图避免使用游标,但现在是时候使用游标了:
DECLARE
@id INT,
@first_name VARCHAR(50),
@last_name VARCHAR(50),
@middle_initial CHAR(1)
DECLARE people_cursor CURSOR FOR
SELECT
Node.value('Id[1]', 'Int'),
Node.value('FirstName[1]', 'varchar(50)'),
Node.value('LastName[1]', 'varchar(50)'),
Node.value('MI[1]', 'char(1)')
FROM
@people_xml.nodes('/ArrayOfPeople/Person') TempXML (Node)
OPEN people_cursor
FETCH NEXT FROM people_cursor INTO @id, @first_name, @last_name, @middle_initial
WHILE (@@FETCH_STATUS = 0)
BEGIN
EXEC Your_Proc
@id = @id,
@first_name = @first_name,
@last_name = @last_name,
@middle_initial = @middle_initial
FETCH NEXT FROM people_cursor INTO @id, @first_name, @last_name, @middle_initial
END
CLOSE people_cursor
DEALLOCATE people_cursor
注意:这一切都是我的头脑。我不太多使用XML,因此可能需要更正语法,您需要添加错误处理等。