如何从SQL Server 2012中的DB列捕获文本?

时间:2015-12-09 16:42:52

标签: sql-server stored-procedures

enter image description here我有一个webpack-dev-server列,长度超过80,0000个字符。

根据转换规则,我必须编写一个SQL脚本,它将在以下步骤中标注notes列:

  • notes
  • 中的前300个字符
  • Column_A
  • 中的下一个300个字符
  • Column_B
  • 中的下一个300个字符

等等。

所以我正在寻找如下输出:

enter image description here

对于每个客户端ID,其长度为notes列的长度。

3 个答案:

答案 0 :(得分:1)

哎哟!这是一个非常复杂的要求。你需要结合一些技巧来解决这个问题。

首先,您需要创建其他行。实现此目标的一种方法是通过recursion。在下面的示例中,我计算了每个客户端ID所需的行数。然后我使用递归来创建它们。

您还需要将每行分成3 300个字符块。在我的例子中,我使用了3个3个字符的块,因此它更容易阅读。但该原则将扩大规模。使用SUBSTRING和记录编号,您可以计算每列的起点。

我在名为Raw的CTE中创建了一些示例记录。这允许任何人按照堆栈数据交换(下面的链接)上的示例进行操作。

Example

strs = pytesseract.image_to_string(Image.open('binarized_body.png'))
  File "C:\Python35x64\lib\site-packages\pytesseract\pytesseract.py", line 167, in image_to_string
    return f.read().strip()
  File "C:\Python35x64\lib\encodings\cp1252.py", line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 20: character maps to <undefined>

答案 1 :(得分:1)

以下是如何执行此操作的方法:

DECLARE @c TABLE(ID INT, Notes VARCHAR(26))
INSERT INTO @c VALUES
(1, 'abcdefghijklmnopqrstuvwxyz'),
(2, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')

DECLARE @size INT = 26
DECLARE @chunk INT = 5

;WITH tally AS(SELECT 1 s1, @chunk + 1 s2, 2*@chunk + 1 s3
               UNION ALL
               SELECT s3 + @chunk, s3 + 2*@chunk, s3 + 3*@chunk FROM tally
               WHERE s3 < @size)
SELECT c.ID, 
       SUBSTRING(Notes, t.s1, @chunk) A, 
       SUBSTRING(Notes, t.s2, @chunk) B, 
       SUBSTRING(Notes, t.s3, @chunk) C
FROM @c c
CROSS JOIN tally t
ORDER BY c.ID, t.s1

输出:

ID  A       B       C
1   abcde   fghij   klmno
1   pqrst   uvwxy   z
2   ABCDE   FGHIJ   KLMNO
2   PQRST   UVWXY   Z

说明

计数表会返回您将在substring函数中使用的起始位置。对于上面的配置,它返回:

s1  s2  s3
1   6   11
16  21  26

为此你使用递归cte,它在3个起始位置的行之间传播起始位置。其余的应该很容易理解。

答案 2 :(得分:0)

可以使用简单的循环

获得所需的结果
/* Declare a temperory table for storing the results */
    DECLARE @Result_TABLE AS TABLE
    (   
     CustomerId     BIGINT
    ,ColA           VARCHAR(300)
    ,ColB           VARCHAR(300)
    ,ColC           VARCHAR(300)
    )

    DECLARE @CustomerCount INT      --To store customer count
    DECLARE @IteratorForCustomers INT = 1 --To iterate for each customers
    /* Get Count of cutomers */
    SELECT @CustomerCount = COUNT (1) FROM Customers 

    DECLARE @CustomerId BIGINT  --To store customer id in looping
    DECLARE @TempNote VARCHAR(MAX) -- To store customer note of each customer in looping
    /* Loop for all customers */
    WHILE (@IteratorForCustomers <=@CustomerCount)
    BEGIN
        ;WITH CTE AS
        (
        SELECT 
         ROW_NUMBER() OVER (ORDER BY CustomerID ) AS RowId
        ,CustomerId
        ,Customer_Note
        FROM Customers
        )
        SELECT
          @CustomerId = a.CustomerId
         ,@TempNote = a.Customer_Note
        FROM CTE a
        WHERE 
        RowId = @IteratorForCustomers

        /* Loop for generating each row with three columns */
        WHILE (LEN(@TempNote)>0)
        BEGIN
            INSERT INTO @Result_TABLE 
            VALUES 

            (
            @CustomerId,SUBSTRING(@TempNote,1,300),SUBSTRING(@TempNote,301,300),SUBSTRING(@TempNote,601,300)
            )

            SET @TempNote = CASE WHEN LEN(@TempNote)>900 THEN   SUBSTRING(@TempNote,901,LEN(@TempNote)-900)
                            ELSE NULL END


        END

        SET @IteratorForCustomers = @IteratorForCustomers + 1

    END

    SELECT * FROM @Result_TABLE