0

我有一个 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 文件输入到数据库中,只需执行以文件名和列名作为参数的过程即可。

4

1 回答 1

1

就您的代码而言,您必须注意一些事项才能使其正常工作。

让我们来看看:

  1. TRUNCATE TABLE [dbo.Student]

    我相信你在默认模式中截断表学生。所以,应该是

    TRUNCATE TABLE Student
    

    或者

    TRUNCATE TABLE dbo.Student
    

    由于表名中没有特殊字符或关键字,因此请忘记方括号。

  2. SELECT @x = P FROM OPENROWSET (BULK @NewName, SINGLE_BLOB) AS Student(P)

    您无法参数化OPENROWSET BULK文件读取。唯一的方法是使用动态 SQL,见这个

    另一个问题是将 varbinary BLOB 分配给 xml 变量,如果没有类型转换,它将无法工作,例如CAST(P as xml). 请注意您真正加载的内容,因为格式不正确的 XML 段会在此处引发错误。

  3. 另一个问题是使用sp_xml_preparedocument过程。你真的需要吗?使用这种 XML 解析可能会限制您的 xml 资源。此外,如果您忘记调用(或因错误而跳过)sp_xml_removedocument,您因此而出错。AFAIK,服务器重启将在这里有所帮助。

    注意: sp_xml_preparedocument 易受攻击,因此请注意您的 XML 文件来自何处。

当您清除这一点时,一些问题仍然悬而未决:您需要什么样的第二个参数(列名)以及为什么?它应该是一个 XML 参数吗?它是否应该用于提示应该从批量加载的 xml 根目录中提取什么样的孩子?

当你解决这个问题时,我相信可以构造一个存储过程,但不能没有一些动态表达式。

于 2013-07-18T21:57:29.097 回答