【问题标题】:How to store semicolon separated long string into multiple columns?如何将分号分隔的长字符串存储到多列中?
【发布时间】:2018-02-23 00:13:53
【问题描述】:

基本上由于实时服务器的限制,我不能使用文本文件,所以我需要在 T-SQL 代码中对数据进行硬编码。

所以首先我从这样的文本文件中创建了字符串:

("001122;Sale Item 1", "001123;Sale Item 23", "001124;Sale Item 24", .... )  

我有这个表结构:

DECLARE @Product TABLE(ProductCode INT NOT NULL, Description nvarchar(100) NOT NULL)

首先我需要将代码和描述存储在一个表变量中。完成后,我可以轻松地将其映射到物理表并更新记录。

我怎样才能实现类似于:

insert into @Product(ProductCode, Description) 
values ("001122;Sale Item 1", "001123;Sale Item 23", "001124;Sale Item 24", .... )
 Code        Description

 001122      Sale Item1
 001123      Sale Item2
 001124      Sale Item3

【问题讨论】:

  • 您的 ProductCode 是 INT,但您有前导零。如果您使用数据类型 INT,它们将丢失
  • 如果你硬编码你的价值观,你为什么不自己手动插入呢?插入@Product(ProductCode, Description) 值 ('001122','Sale Item 1'), ('001123','Sale Item 23'),('001124','Sale Item 24')
  • 这似乎不是您的主要问题,而是您想要修复的一个古怪的解决方法。解决你的主要问题不是更好吗?
  • 听起来像是 CSV 到 SQL 的转换。看到这个问题:stackoverflow.com/questions/15242757/…

标签: sql sql-server tsql


【解决方案1】:

如果您有像示例中那样的固定格式,那么您只需使用 CHARINDEXSUBSTRING 即可实现所需的输出

SELECT 
    SUBSTRING(description, 0, CHARINDEX(';', DESCRIPTION, 0)) code,
    SUBSTRING(description, CHARINDEX(';', DESCRIPTION, 0)+1, LEN(DESCRIPTION)) Description  
FROM @Product

输出:

 code       Description
------------------------
001122      Sale Item 1
001123      Sale Item 23
001124      Sale Item 24

【讨论】:

  • 当我运行你的代码时,我的输出是一行而不是多行。
【解决方案2】:

我们来了,伙计:

DECLARE @MyString nvarchar(max) = '"001122;Sale Item 1", "001123;Sale Item 23", "001124;Sale Item 24"';

DECLARE @delimiter1   nvarchar(1)
      , @delimiter2   nvarchar(1)
      , @Start1       int
      , @End1         int
      , @Length       int
      , @cNEXTVALUE   nvarchar(1000)
      , @cNEXTVALUE2  nvarchar(1000)
      , @StringLength int;

DECLARE @Product TABLE ( 
                       ProductCode int NOT NULL
                     , Description nvarchar(100) NOT NULL );

SET @MyString = RTRIM(LTRIM(@MyString));
SET @MyString = REPLACE(@MyString, CHAR(13), '');
SET @MyString = REPLACE(@MyString, CHAR(10), '');

SET @delimiter1 = ';';
SET @delimiter2 = ',';
SET @MyString = REPLACE(@MyString, '"', '')+@delimiter2;
SET @StringLength = LEN(@MyString);

SELECT @Start1 = 0
     , @End1 = CHARINDEX(@delimiter1, @MyString, 1);

SELECT @Length = @End1 - @Start1;

WHILE @Length > 0
    BEGIN

        SET @cNEXTVALUE = SUBSTRING(@MyString, @Start1, @Length);
        SET @Start1 = @End1 + 1;

        SET @End1 = CHARINDEX(@delimiter2, @MyString, @Start1);
        SELECT @Length = @End1 - @Start1;

        SET @cNEXTVALUE2 = SUBSTRING(@MyString, @Start1, @Length);

        IF LEN(RTRIM(LTRIM(@cNEXTVALUE))) > 0
            BEGIN
                INSERT INTO @Product
                       ( ProductCode
                       , Description
                       ) 
                VALUES
                       ( @cNEXTVALUE, @cNEXTVALUE2 );
            END;

        SET @Start1 = @End1 + 2;
        SET @End1 = CHARINDEX(@delimiter1, @MyString, @Start1);
        SELECT @Length = @End1 - @Start1;

    END;

SELECT *
  FROM @Product;

【讨论】:

    【解决方案3】:

    我为你制作了一个样本,请检查一下

    declare @Questions varchar(100)= '"001122;Sale Item 1", "001123;Sale Item 23", "001124;Sale Item 24"'
    
    DECLARE @myXML AS XML  = N'<H><r>' +Replace(@Questions, ',', '</r><r>') + '</r></H>'
     select @myXML
    
    ;WITH cte 
    AS (
        SELECT CAST(N'<H><r>' +  Replace(Vals.id.value('.', 'NVARCHAR(50)') ,';' , '</r><r>') + '</r></H>' as XML) AS val 
        FROM @myXML.nodes('/H/r') AS Vals(id) 
    )
    
    ,mycte1 as ( 
    SELECT   distinct
        Replace( S.a.value('(/H/r)[1]', 'NVARCHAR(50)') , '"', '') AS c1,   
        Replace( S.a.value('(/H/r)[2]', 'NVARCHAR(50)') , '"', '') AS c2
    
    FROM cte CROSS APPLY val.nodes('/H/r') S(a)
    )
    
    select * from mycte1 
    

    输出将是

    c1      c2
    001123  Sale Item 23
    001124  Sale Item 24
    001122  Sale Item 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多