我有一个SQL Server程序,我希望将文件名作为参数。
我的代码是:
CREATE PROCEDURE XMLTOSQLTABLE1 @NewName nvarchar(50)
AS
TRUNCATE TABLE [dbo.Student]
DECLARE @x XML
SELECT @x = P
FROM OPENROWSET (BULK @NewName, SINGLE_BLOB) AS Student(P)
DECLARE @hdoc int
EXEC sp_xml_preparedocument
@hdoc OUTPUT,
@x
INSERT INTO [dbo.Student]
SELECT *
FROM OPENXML (@hdoc, '/class_list/student',2)
WITH (
name varchar(100),
grade varchar(100))
EXEC sp_xml_removedocument @hdoc
GO
我希望将文件名和列名作为我的参数,这样我只需执行以文件名和列名作为参数的过程,就可以轻松地将任何XML文件输入到数据库中。
答案 0 :(得分:1)
就您的代码而言,您必须注意一些事情才能发挥作用。
让我们看看:
TRUNCATE TABLE [dbo.Student]
我相信您在默认架构中截断表Student。 所以,它应该是
TRUNCATE TABLE Student
或
TRUNCATE TABLE dbo.Student
由于表名中没有特殊的字符或关键字,请忘记 方括号。
SELECT @x = P FROM OPENROWSET (BULK @NewName, SINGLE_BLOB) AS Student(P)
您无法参数化OPENROWSET BULK
文件读取。
唯一的方法是使用动态SQL see this。
另一个问题是将varbinary BLOB分配给xml变量
如果没有类型转换,则无效,例如CAST(P as xml)
。请注意
你正在加载什么,因为非格式良好的XML段将会
在这里抛出错误。
另一个问题是使用sp_xml_preparedocument
程序。你真的需要它吗?
使用这种XML解析可以限制您的xml资源。另外,如果你忘了
要调用(或因错误而跳过)sp_xml_removedocument
您将收到错误
因为这。 AFAIK,服务器重启将有助于此。
注意:sp_xml_preparedocument很容易受到攻击,因此请注意XML文件的位置 来自。
当你清除它时,一些问题仍然存在:你需要什么样的第二个参数(列名)以及为什么?它应该是XML参数吗?是否应该使用提示从批量加载的xml根中提取哪种类型的孩子?
当你对它进行排序时,我相信可以构建一个存储过程,但不能没有一些动态表达式。