如何将字符串传递给批量插入而不是文件?

2024-03-21

我曾经使用批量插入命令来转换 Csv 文件 int 表。最近,我将 CSV 文件保存为 SQL Server 中的 VarBinary 值。现在我可以通过使用 CAST 和 CONVERT 函数将其类型转换为 Varchar 来从 Varbinary 文件中获取数据。但是现在我遇到一个问题,无法使用批量插入将包含 csv 内容的 Varchar 字符串转换为表。任何人都可以帮助我吗 我的示例代码如下:

--@String contains varchar value of CSV file content.  
SET @sql = 'BULK INSERT TempCsv
FROM  ''' + @String  + '''
WITH
(
    FIRSTROW = 2,
    FIELDTERMINATOR = '','',  
    ROWTERMINATOR = ''\n'',   
    TABLOCK
)'

请帮助我。有没有任何方法或替代方法可以将数据从 csv 字符串插入到表中。


编辑:允许多个字符分隔符

我就是这样解决的。它涉及:

  • 表值函数 (xftSplit) 用于将换行符 (char(10)) 拆分为表格行
  • 标量函数 (fSubstrNth) 用于在给定分隔符的情况下提取行的第 n 个字段
  • 标量函数 (fPatIndexMulti) 用于查找分隔符的第 n 个索引
  • (可选)替代方案Right接受负值的函数
  • 最后,在您的解决方案中使用一些特定的代码,因为 SQL 不允许动态表函数定义(换句话说,您不能SELECT来自具有动态列的函数)

现在,对于代码片段:

xftSplit

-- =============================================
-- Author:      Bernardo A. Dal Corno
-- Create date: 15/07/2014
-- Description: Quebra valores a partir de caracteres e retorna lista em tabela
-- =============================================
CREATE FUNCTION [dbo].[xftSplit] 
(
    @Texto varchar(max),
    @Splitter varchar(3)
)
RETURNS 
@Lista TABLE 
(
    ValoresQuebrados varchar(8000)
)
AS
BEGIN
DECLARE @Pos Smallint

  While len(@Texto)>0 BEGIN
    SET @Pos = Patindex('%'+@Splitter+'%',@Texto)

    IF @Pos > 0 BEGIN
      INSERT INTO @Lista
      SELECT left(@Texto, @Pos-1)

      SET @Texto = right(@Texto, len(@Texto)-@Pos)
    END
    ELSE BEGIN
      INSERT INTO @Lista
      SELECT @Texto

      SET @Texto = ''
    END
  End

  RETURN 
END

fSubstrNth

-- =============================================
-- Author:      Bernardo A. Dal Corno
-- Create date: 18/07/2017
-- Description: substring com 2 PatIndex limitando inicio e fim
-- =============================================
CREATE FUNCTION fSubstrNth
(
  @Text varchar(max),
  @Sep varchar(3),
  @N int --Nth campo
)
RETURNS varchar(max)
AS
BEGIN
  DECLARE @Result varchar(max)

  IF @N<1 RETURN ''
  IF @N=1
    SET @Result = substring(@Text, 1, dbo.fPatIndexMulti(@Sep,@Text,1)-1)
  ELSE
    SET @Result = substring(@Text, dbo.fPatIndexMulti(@Sep,@Text,@N-1)+LEN(@Sep), CASE WHEN dbo.fPatIndexMulti(@Sep,@Text,@N)>0 THEN dbo.fPatIndexMulti(@Sep,@Text,@N)-dbo.fPatIndexMulti(@Sep,@Text,@N-1)-LEN(@Sep) ELSE LEN(@Text)+1 END)

  RETURN @Result
END

fPatIndexMulti

-- =============================================
-- Author:      Bernardo A. Dal Corno
-- Create date: 17/07/2017
-- Description: recursive patIndex
-- =============================================
CREATE FUNCTION [dbo].[fPatIndexMulti]
(
  @Find varchar(max),
  @In varchar(max),
  @N tinyint
)
RETURNS int
AS
BEGIN
  DECLARE @lenFind int, @Result int, @Texto varchar(max), @index int
  DECLARE @i tinyint=1

  SET @lenFind = LEN(@Find)-1
  SET @Result = 0
  SET @Texto = @In
  WHILE (@i <= @N) BEGIN
    SET @index = patindex('%'+@Find+'%',@Texto)
      IF @index = 0 RETURN 0
    SET @Result = @Result + @index
    SET @Texto = dbo.xRight(@Texto, (@index + @lenFind)*-1)

    SET @i = @i + 1
  END
  SET @Result = @Result + @lenFind*(@i-2)

  RETURN @Result
END

xRight

-- =============================================
-- Author:      Bernardo A. Dal Corno
-- Create date: 06/01/2015
-- Description: Right inverso (para nros < 0)
-- =============================================
CREATE FUNCTION [dbo].[xRight] 
(
  @Texto varchar(8000),
  @Qntd int
)
RETURNS varchar(8000)
AS
BEGIN
  DECLARE @Result varchar(8000)

  IF (Len(@Texto) = 0) OR (@Qntd = 0)
    SET @Result = ''
  ELSE IF (@Qntd > 0) 
      SET @Result = Right(@Texto, @Qntd)
    ELSE IF (@Qntd < 0)
    SET @Result = Right(@Texto, Len(@Texto) + @Qntd)

  RETURN @Result
END

具体代码

SELECT 
     acolumn = 'any value',
     field1 = dbo.fSubstrNth(line,',',1),
     field2 = dbo.fSubstrNth(line,',',2),
     anothercolumn = 'set your query as you would normally do',
     field3 = (CASE dbo.fSubstrNth(line,',',3) WHEN 'C' THEN 1 ELSE 0 END)
FROM (
  SELECT line = ValoresQuebrados FROM dbo.xftSplit(@StringVariable, char(10))
) lines

注意:

  • fSubstrNth接收要从该行中提取的第 n 个字段
  • xftSplit接收一个变量,其中包含您想要批量处理的字符串(无论来源如何)和一个char(10)作为分离器\n,但也可以是其他任何东西
  • 该查询可以与任何其他查询一样。这意味着它可以存储在过程、表函数、视图等中。您可以按照您希望的任何顺序提取部分或全部字段,并按照您想要的方式进行处理
  • 如果在存储过程中使用,您可以创建一种通用方法来创建查询和临时表,以加载带有动态列的字符串,但您必须调用另一个过程才能使用数据或创建一个特定的查询,如上面的相同的过程(这将使其非通用,只是更可重用)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将字符串传递给批量插入而不是文件? 的相关文章

  • 使用 MSSQL 中的附加 max() 条件从数据库中检索每组中的最后一条记录

    这是一个后续问题从数据库中检索每组中的最后一条记录 SQL Server 2005 2008 https stackoverflow com questions 4751913 retrieving last record in each
  • 如何将 OLE 自动化日期值转换为 SQL Server 中的日期

    我的应用程序存储日期作为 OLE 自动化与DateTime ToOADate 命令 我需要创建一个 SQL 视图来显示存储的日期 如何快速将双精度数转换为日期 Does SELECT CAST CASE WHEN OLEFLOAT gt 0
  • 如何查询最近7天的总计?

    我正在使用 SQL Server 2008 我想编写一个查询来提供给定天数的总活动量 具体来说 我想统计过去 7 天每天的总票数 我的桌子看起来像这样 VoteID VoteDate Vote BikeID 1 2012 01 01 08
  • 警告:mysqli_stmt::bind_param():变量数量与准备好的语句中的参数数量不匹配[重复]

    这个问题在这里已经有答案了 我收到以下错误 Warning mysqli stmt bind param Number of variables doesn t match number of parameters in prepared
  • MySql:将多项选择数据存储在数据库中

    我的表单中有一个复选框列表 用户可以选择其中任何一个 也可以选择全部 认为用户选择他感兴趣的运动类型 我需要最好的数据库结构来存储这个用户选择 这样 将来我就可以获得所有这些数据 我想 我无法将每个 用户 ID 运动 选择作为新行存储在数据
  • #DELETE 在 Access 中查看 SQL Server 表

    今天早上又出现了一个新问题 我的数据库驻留在 SQL Server 上 并使用 Access 作为前端 其中一个已经使用了至少 10 年的数据库今天突然停止工作 我发现这个问题影响了 2 个 可能更多 我没有检查所有 表 当我在访问中打开表
  • 使用不存在和联接的 SQL 查询到 LINQ 语法

    我的 SQL 查询如下所示 在 SQL 中运行良好 我需要将其转换为 LINQ 语法 SQL SELECT Key Id FROM LocalizationKeys AS lk WHERE NOT EXISTS SELECT 1 FROM
  • 为列名创建动态选择获取值 - 在 SQL Server 中

    请帮助我创建一个选择 SQL 语句 其中的结果列名称是从原始表中的列值获取的 表名是Device Part 用户可以输入很多DeviceCode其中有许多动态PartTypeName PartTypeName 值为PartInfo 这可能有
  • SQL Server 将 SP_EXECUTESQL 识别为对象而不是过程名称

    我在用DBContext Database SqlQuery
  • 创建用于插入、修改和删除的数据库触发器的正确​​语法是什么

    我有一个看起来像是 SQL Server 中数据库触发器的基本场景 但我遇到了一个问题 我有桌子Users 身份证 姓名 电话等 我有桌子用户历史记录 id user id 操作 字段 时间戳 我想要一个数据库触发器 可以随时插入 更新或删
  • 将插入与 select 语句合并

    这对我有用 MERGE Table1 AS tgt USING SELECT TOP 1 FROM Table2 SELECT itmid FROM Table3 WHERE id id as a WHERE id id AS src ON
  • BCP 语法问题

    总之 我正在尝试编写一个可以每天从 SQL Server 2008 实例上的批处理文件运行的查询 我以前从未使用过 BCP 但在查看了一些在线示例后 我尝试创建一个真正的基本查询来测试计算机上的进程和权限 然后再将选择查询扩展到所需的数据集
  • 需要帮助在 MS Access 中实施完全外部联接

    我无法让查询在 Access 中正常工作 我需要 dbo cardpurchases 和 dbo vendors 上的完整外部联接 以便所有所有供应商都将出现在查询中 无论是否在该供应商处进行购买 但 Access 不支持完全外部联接 我还
  • SQL Server 全文搜索 - 是否可以在单词中间进行搜索?

    我的数据库有全文搜索 是否可以在单词中间搜索某些文本 例如 我有一个描述列 其中包含以下文本 Revolution 是否可以搜索 EVO 并让它在 革命 一词中找到它 或者我是否一直在做 LIKE SELECT FROM Table WHE
  • SQL Server 2005 - 达到表行大小限制

    有没有一种干净的方法可以在向表添加新列之前确定表的行大小 并且不超过 8060 字节的限制 例如 如果表行长度当前为 8055 字节 并且我想添加日期时间 8 字节 则这将结束 因为它将变为 8063 字节 不包括空映射 但是 如果我添加一
  • SQL 解析键值字符串

    我有一个像这样的逗号分隔字符串 key1 value1 key2 value2 key3 value3 key1 value1 1 key2 value2 1 key3 value3 1 我想将它解析成一个如下所示的表 Key1 Key2
  • 在分布式事务中手动登记后,使用 enlist=false 的连接不会关闭

    我有一个分布式事务上下文使用ServiceDomain 在其中 我打开一个 SQL 连接 其中连接字符串指定Enlist false 这样它就不是自动地被纳入交易 然后 如果我使用手动在分布式事务中登记连接EnlistDistributed
  • 使用 SQL Server 作为具有多个客户端的数据库队列

    给定一个充当队列的表 如何最好地配置表 查询 以便多个客户端同时处理队列 例如 下表指示了工作人员必须处理的命令 当worker完成后 它会将处理后的值设置为true ID COMMAND PROCESSED 1 true 2 false
  • 如何跟踪数据库连接泄漏

    我们有一个应用程序似乎存在连接泄漏 SQL Server 表示已达到最大池大小 我独自一人在我的开发机器上 显然 只需导航应用程序 我就会触发此错误 SQL Server 活动监视器显示大量正在使用我的数据库的进程 我想查找哪些文件打开连接
  • 动态/条件 SQL 连接?

    我在 MSSQL 表 TableB 中有数据 其中 dbo tableB myColumn 在特定日期后更改格式 我正在做一个简单的连接到该表 Select dbo tableB theColumnINeed from dbo tableA

随机推荐