Умножение данных внутри хранимой процедуры SQL Server - PullRequest
1 голос
/ 29 июня 2011

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. Обновить поле Кол-во с результатом, где кол-во пустое или пустое

У меня нетидея, как я могу сделать это внутри SQL Server?Я уверен, что хранимая процедура будет полезна!

Ответы [ 5 ]

3 голосов
/ 29 июня 2011

Вот одна попытка.Он делает много предположений, например, что до ПОСЛЕ размера 2 не будет пробела и что обе стороны * (или 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 в столбце.Поддерживать это будет кошмар, не говоря уже о том, чтобы столбец размера получал согласованные данные (и что ваша формула будет работать против всех будущих реализаций).

Я также предлагаю не иметь имен столбцов со специальными символами(например, пробелы).Никому не нравится вводить квадратные скобки, когда их можно избежать.

Наконец, если вы можете принудительно вводить данные при вводе, вы должны рассмотреть вычисляемый столбец или представление.Вам не нужно постоянно возвращаться и обновлять таблицу после факта.

1 голос
/ 29 июня 2011

Если формат фиксированный, вы можете использовать такие функции, как patindex и substring для анализа размера:

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

Вот полный пример в ODATA.

0 голосов
/ 30 июня 2011

Я удивлен, что никто не предложил вычисляемый столбец.Я согласен с Аароном о нормализации структуры данных.Один столбец не должен иметь 2 измерения и тип.Это должно быть 3 столбца.Это не должно быть разрешено в базе данных.

Как и для вычисляемого столбца - это сэкономит на триггерах.В SQL Server перейдите в таблицу, измените столбец QTY и задайте «Спецификация вычисляемого столбца» для нужной функции.Вы можете проверить больше о вычисляемых столбцах здесь: http://msdn.microsoft.com/en-us/library/ms191250.aspx

0 голосов
/ 30 июня 2011

ОБЪЯВИТЬ @foo TABLE
(Id int,
[Ship Qty] INT, Size VARCHAR (32), Qty Float
);

INSERT @foo (Id, [Кол-во кораблей], размер)

выберите Id, [Кол-во кораблей], [Размер] из PlacedOrderDetails, где Qty равно Null;
UPDATE @foo SETКол-во = [Кол-во отправления] * CONVERT (INT, LEFT (размер, CHARINDEX ('X', размер) -1)) * CONVERT (Float, SUBSTRING (размер, CHARINDEX ('X', размер)) +1, CHARINDEX ('', Размер) -CHARINDEX (' X ', Размер)))
ГДЕ CHARINDEX (' X ', Размер)> 0 И CHARINDEX (' ', Размер)> 0 И КОЛИЧЕСТВО НУЛЬ;

SELECT Id, [Кол-во кораблей], Размер, Кол-во ОТ @foo;

- ***** - Результат этого запроса отличный - Проблема в том, что он вставляется во временную таблицу - Я хочу обновить егомгновенно в родительской таблице: PlacedOrderDetails

0 голосов
/ 30 июня 2011

Вы можете попробовать 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
...