SQL Server存储过程中的数据乘法

时间:2011-06-29 19:42:37

标签: sql-server sql-server-2005 sql-server-2008

SQL Server 2008:我有一个包含三列Ship Qty, Size, Qty的表。

我们需要通过将另外两列相乘来更新列Qty

目前这是表格中的数据

Ship Qty            Size              Qty
2                   1*100  EA         NULL
3                   3*20 ML           

查询后的预期结果

Ship Qty            Size              Qty
2                   1*100  EA         200
3                   3*20 ML           180
  1. 将尺寸分割为尺寸1(在X之前)和尺寸2(在X之后)(例如1X100 EA =>尺寸1 = 1,SIze2 = 100)
  2. 乘船数量*尺寸1 *尺寸2
  3. 使用qty为null或为空的结果更新字段数量
  4. 我不知道,我怎么能在SQL Server中做到这一点?我确信存储过程会有所帮助!

5 个答案:

答案 0 :(得分:3)

这是一次尝试。它做了很多假设,例如在AF2 Size2之前不会出现任何空间,并且*(或者描述中的X - 它是?)的两侧都可以转换为INT。

    DECLARE @foo TABLE
    (
        [Ship Qty] INT,
        Size VARCHAR(32),
        Qty INT
    );

    INSERT @foo([Ship Qty], Size)
    SELECT 2, '1*100 EA'
    UNION SELECT 3, '3*20 ML';

    UPDATE @foo SET
        Qty = [Ship Qty] * CONVERT(INT, LEFT(Size, CHARINDEX('*', Size)-1)) * 
        CONVERT(INT, SUBSTRING(Size, CHARINDEX('*', Size)+1, 
            CHARINDEX(' ', Size)-CHARINDEX('*', Size)))
    WHERE
        CHARINDEX('*', Size) > 0
        AND CHARINDEX(' ', Size) > 0
        AND Qty IS NULL;

    SELECT [Ship Qty], Size, Qty FROM @foo;

我强烈建议您更好地存储这些数据。而不是将“1 * 100 EA”存储1存储在一列中,将100存储在一列中,而将EA存储在一列中。这将是一个维持的噩梦,更不用说强制执行size列获取一致的数据(并且您的公式将适用于所有未来的实现)。

我还建议没有包含特殊字符的列名(例如空格)。没有人喜欢在可以避免的情况下输入方括号。

最后,如果您可以对输入强制执行数据,则应考虑计算列或视图。事后你不应该经常回去更新表格。

答案 1 :(得分:1)

如果格式已修复,您可以使用patindexsubstring等函数来解析大小:

select  [Ship Qty]
,       Size
,       [Ship Qty] * Size1 * Size2
from    (
        select  cast(substring(Size, 1, StarPos-1) as int) as Size1
        ,       cast(substring(Size, StarPos+1, SpacePos-StarPos-1) as int) 
                    as Size2
        ,       *
        from    (
                select  patindex('%*%', Size) as StarPos
                ,       patindex('% %', Size) as SpacePos
                ,       *
                from    @t
                ) as SubQueryAlias1
        ) as SubQueryAlias2

Here's a full example at ODATA.

答案 2 :(得分:0)

您可以尝试PARSENAME

-- create simple data, copy from Aaron Bertrand
DECLARE @foo TABLE
(
    [Ship Qty] INT,
    Size VARCHAR(32),
    Qty INT
);

INSERT @foo([Ship Qty], Size)
SELECT 2, '1*100 EA'
UNION SELECT 3, '3*20 ML'
UNION SELECT 3, '1*4.7 ML';

-- calcuate Qty    
WITH f AS
(SELECT  [Ship Qty],'[' + REPLACE(REPLACE(Size,'*','].['),' ','].[')+']' as size,Qty
 FROM @foo
 )
SELECT  [Ship Qty],PARSENAME(size,3) as Size1,PARSENAME(size,2) as Size2,
     1.0*[Ship Qty] * PARSENAME(size,3) * PARSENAME(size,2) AS Qty
FROM    f

答案 3 :(得分:0)

DECLARE @foo表
( Id int,
[船舶数量] INT, 尺寸VARCHAR(32), 数量浮动
);

INSERT @foo(Id,[Ship Qty],Size)

从PlacedOrderDetails中选择Id,[Ship Qty],[Size],其中Qty为Null;
 更新@foo  SET Qty = [发货数量] * CONVERT(INT,LEFT(尺寸,CHARINDEX('X',尺寸)-1))* CONVERT(浮点,SUBSTRING(尺寸,CHARINDEX('X',尺寸)+1,CHARINDEX( '',尺寸)-CHARINDEX('X',尺寸)))
CHARINDEX('X',尺寸)> 0和CHARINDEX('',尺寸)> 0和Qty IS为空;

SELECT Id,[Ship Qty],Size,Qty FROM @foo;

- * **** - 此查询结果很棒 - 问题在于,它正在插入Temp Table - 我想立即在父表:PlacedOrderDetails

上更新它

答案 4 :(得分:0)

我很惊讶没有人建议使用计算列。 我同意Aaron重新规范数据结构。一列不应具有2个维度和类型。这应该是3列。这不应该在数据库中允许。

至于计算列 - 这将节省触发器。 在SQL Server中,进入表格,修改列QTY并将“计算列规范”设置为所需的功能。 您可以在此处查看有关计算列的更多信息:http://msdn.microsoft.com/en-us/library/ms191250.aspx