sql >> データベース >  >> RDS >> Sqlserver

SQLはvarchar変数を別のvarchar変数と比較します

    1) 中長期的には、このような間違いを避けるために、このデータベースを正規化したいと思います:文字列/VARCHAR 列内に値のリストを保存します。たとえば、次の多対多テーブルを使用します:

    CREATE TABLE dbo.BillItem (
        ID INT IDENTITY(1,1) PRIMARY KEY,
        BilldID INT NOT NOT NULL REFERENCES dbo.Bill(BilldID),
        ItemID INT NOT NULL REFERENCES dbo.Item(ItemID),
        UNIQUE (BillID, ItemID) -- Unique constraint created in order to prevent duplicated rows
    );
    

    この場合、2 つの項目を持つ 1 つの請求書は、dbo.BillItem に 2 つの行を挿入する必要があることを意味します。

    2) 元の要求に戻る:1 回限りのタスクで、XML と XQuery を使用します (このソリューションは SELECT ステートメントで終了しますが、UPDATE に変換するのは簡単です):

    DECLARE @iCountRef VARCHAR(100) = '1,2,3'
    
    DECLARE @SourceTable TABLE (
        BillId          INT,
        LineReference   VARCHAR(8000)
    )
    
    INSERT @SourceTable (BillId, LineReference)
    VALUES
    (100, '1,2,'),
    (100, '1,2,40,34'),
    (100, '1'),
    (100, '12')
    
    DECLARE @iCountRefAsXML XML = CONVERT(XML, '<a><b>' + REPLACE(@iCountRef, ',', '</b><b>') + '</b></a>')
    
    SELECT  *, STUFF(z.LineReferenceAsXML.query('
        for $i in (x/y)
            for $j in (a/b)
                where data(($i/text())[1]) eq data(($j/text())[1])
            return concat(",", ($i/text())[1])
    ').value('.', 'VARCHAR(8000)'), 1, 1, '') AS NewLineReference
    FROM (
        SELECT  *, CONVERT(XML, 
            '<x><y>' + REPLACE(LineReference, ',', '</y><y>') + '</y></x>' + 
            '<a><b>' + REPLACE(@iCountRef, ',', '</b><b>') + '</b></a>'
        ) AS LineReferenceAsXML
        FROM    @SourceTable s
    ) z
    

    結果:

    BillId      LineReference  NewLineReference LineReferenceAsXML                                                      
    ----------- -------------  ---------------- ------------------------------------------------------------------------
    100         1,2,           1 ,2             <x><y>1</y><y>2</y><y /></x><a><b>1</b><b>2</b><b>3</b></a>             
    100         1,2,40,34      1 ,2             <x><y>1</y><y>2</y><y>40</y><y>34</y></x><a><b>1</b><b>2</b><b>3</b></a>
    100         1              1                <x><y>1</y></x><a><b>1</b><b>2</b><b>3</b></a>                          
    100         12             (null)           <x><y>12</y></x><a><b>1</b><b>2</b><b>3</b></a>                         
    


    1. mysqlは利用可能な最小の+一意のIDを見つけます

    2. OdbcConnectionは漢字を?として返します

    3. 単一の列の評価を計算するための複雑なSQLSELECT

    4. OracleSQLで特定の行を選択しようとして複数の行が返されました