Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server 2005-使用OpenXML与分隔字符串插入记录_Sql Server_Sql Server 2005_Openxml - Fatal编程技术网

Sql server SQL Server 2005-使用OpenXML与分隔字符串插入记录

Sql server SQL Server 2005-使用OpenXML与分隔字符串插入记录,sql-server,sql-server-2005,openxml,Sql Server,Sql Server 2005,Openxml,我有一大堆员工的名字需要插入到表中 我应该这样表示我的数据并使用OpenXML插入数据库:- <Employees> <Employee> Emp1 </Employee> <Employee> Emp2 </Employee> <Employee> Emp2 </Employee> </Employees> Emp1 Emp2 Emp2 或 我应该像Emp1、Emp2、Emp3那样表示员工,拆

我有一大堆员工的名字需要插入到表中

我应该这样表示我的数据并使用OpenXML插入数据库:-

<Employees>
<Employee>
Emp1
</Employee>
<Employee>
Emp2
</Employee>
<Employee>
Emp2
</Employee>
</Employees>

Emp1
Emp2
Emp2

我应该像
Emp1、Emp2、Emp3那样表示员工,拆分字符串,添加到表变量,然后插入到数据库表中


这两种方法之间是否存在性能差异。请注意,这是一个非常简单的结构,XML中没有任何雇员嵌套,字符串中也没有多个分隔符。这个XML也不会用作模式或任何东西。OpenXML会是一种过度使用吗?有人能给我一些指导吗

使用SQL Server XQuery支持,您可以轻松地将XML分解为若干位:

INSERT INTO dbo.Employees(EmployeeName)
   SELECT 
      Data.Emp.value('(.)[1]', 'varchar(100)')
   FROM
      @Input.nodes('/Employees/Employee') AS Data(Emp)

CSV文件就不是这样了,所以我会投票支持XML方法。

根据您使用的SQL版本,还有第三种选择非常简单。如果您使用的是SQL 2008,则可以创建用户定义的表类型

CREATE TYPE [dbo].[IntegerList] AS TABLE(
    [n] [VARCHAR(100)] NOT NULL,
    PRIMARY KEY CLUSTERED 
(
    [n] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
我将其用于整数,但我不明白为什么不能将类型更改为varchar。然后你就这样使用它:

CREATE PROCEDURE [dbo].[CheckIds]
    @Ids    IntegerList READONLY
AS
BEGIN
    SELECT *
    FROM [dbo].[Table]  
    WHERE [Id] IN (SELECT n FROM @Ids)
END
然后在.net代码中设置如下:

int[] Ids = <You id array>
var IdList = new List<SqlDataRecord>();
SqlMetaData[] tvp_definition = { new SqlMetaData("n", SqlDbType.Int) };

foreach (int Id in Ids)
{
    var rec = new SqlDataRecord(tvp_definition);
    rec.SetInt32(0, Id);
    IdList.Add(rec);
}
可能看起来很多,但实际上不是。它非常干净,没有解析xml或字符串的不必要代码


我不记得我最初是在哪里找到这段代码的。我想它可能在这个网站上,但搜索时我找不到它。所以,如果有人发现了它,我会很乐意把它归功于任何人。我只是想与大家分享一下,因为我在2008年不熟悉这一点,觉得这是一种非常干净的方法。

使用表值参数的最大问题是:

1) 不能修改用户定义的表类型。您需要删除并重新创建。 2) 如果用户定义的表类型被另一个对象(即存储过程或函数)引用,则不能删除该表类型


有鉴于此,如果您的UDTT用于多个存储的进程或函数,您需要全部删除它们,删除UDTT,重新创建UDTT,然后重新创建所有SP。

marc\s,谢谢您的时间。在您的体验中,除了易用性之外,您是否看到了任何性能差异(XML/XQuery与CSV)。正如我所说的,SQL Server根本无法处理CSV(或者它会因为大量调用CHARINDEX和子字符串等而变得非常混乱)-因此性能不是真正的问题-使用XQuery,您可以完成它。使用CSV,您需要在客户机上做大量工作(使用应用程序、实用程序或其他东西)。如果您必须使用CSV,请调查SqlBulkCopy类之类的内容—它应该可以满足这一需求purpose@ydobonmai想想维护。我使用了XML方法,它工作正常。+1@marc_s,存储过程调用UDF,UDF接受CSV并返回一个表。但不管怎么说,这确实是一团糟,只是把一团糟放在了别的地方。当你说“所以性能不是一个真正的问题”时,你的意思是使用CSV比XQuery/XML+1 VillageDiot有更多的性能开销。我同意。谢谢你抽出时间。我一直在使用CSV来处理这类事情,现在我希望使用XML/XQuery,因此希望通过一些性能比较来增强我对XML/XQuery的信心。对不起,我应该在问题中提到。我正在使用SQLServer2005。好吧,那就不用担心了。我认为这只在2008年起作用。但我会很快检查的。是的,它只在2008年起作用。对,它被称为表值参数。
sqlCommand.Parameters.Add(new SqlParameter { ParameterName = "@Ids", SqlDbType = SqlDbType.Structured, TypeName = "IntegerList", Value = IdList });