2013-09-22 2 views
1

Я пытаюсь передать концепцию, которую я использую в Java-коде, который я использовал для хранимых процедур SQL, и я не уверен, что это возможно.Обновление различных столбцов в хранимой процедуре

По существу, если у меня есть таблица с 10 столбцами, я хочу иметь возможность обновлять разные комбинации столбцов из одной и той же хранимой процедуры каждый раз. То есть в Java я бы передал карту, содержащую значения, которые я хочу обновить, и прокрутить их и обновить каждое значение ключа в кеше.

Это имеет смысл не изменять подпись метода, чтобы включать в себя имя каждого столбца, а также не иметь большой кусок кода, выполняющий нулевую проверку для каждой переменной, чтобы выяснить, следует ли ее обновлять или нет. Я не уверен, что это возможно, или могут ли определенные серверы баз данных работать с ним (то есть PostgreSQL, Oracle, MySQL) или все они способны на это, но я просто не могу понять синтаксис.

+0

Можете ли вы опубликовать пример кода Java, чтобы было более ясно, чего вы пытаетесь достичь. – calcinai

+0

Это можно сделать с помощью динамического SQL в любой из упомянутых вами СУБД. –

ответ

1

В SQL Server ниже процедура будет работать при условии, таблицу, как это:

CREATE TABLE MyBigTable(
    ID INT NOT NULL PRIMARY KEY, 
    COLUMNA VARCHAR(100) NOT NULL, 
    COLUMNB VARCHAR(100) NOT NULL 
) 

GO 

CREATE PROCEDURE UpdateMyBigTable(@ID INT, @ColumnAValue VARCHAR(100)=NULL, @ColumnBValue VARCHAR(100)=NULL) 
AS BEGIN 
UPDATE MyBigTable 
    SET COLUMNA = CASE WHEN @ColumnAValue IS NULL THEN COLUMNA ELSE @ColumnAValue END, 
    COLUMNB = CASE WHEN @ColumnBValue IS NULL THEN COLUMNB ELSE @ColumnBValue END 
WHERE ID = @ID 
    AND ((COLUMNA <> @ColumnAValue AND @ColumnAValue IS NOT NULL) OR (COLUMNB <> @ColumnBValue AND @ColumnBValue IS NOT NULL)); 
END 

GO 

Однако это не на самом деле перечислять через поля, который, что вы спрашиваете. Это трудно сделать в SQL Server без перехода в динамический SQL.

+1

Во втором случае, как вы различаете столбец, который вы хотите установить в NULL, и столбец, значение которого вы не хотите изменять? –

+0

Вы правы. Я собираюсь это вытащить. Решение становится намного более сложным, если вы собираетесь разрешать NULL, потому что я полагаю, вам придется попасть в запрещенные значения, такие как отправка низких символов ASCII. При повторном чтении любое решение на самом деле не работает для заявленного случая OP, так как запрашивает способ перебрать столбцы. – NYCdotNet

+0

Если вы это сделаете, вы фактически обновите значения, даже если оно имеет собственное существующее значение. Из памяти это приводит к тому, что индексы пересчитываются так медленнее, чем вычисление условного оператора в начале. –

0

Для лучшей производительности либо используйте динамический SQL, либо оператор IF с инструкцией SQL для каждой возможной комбинации параметров запроса.

Если вы можете вносить предложения IF для каждого возможного решения, идите с этим - он стабилен, безопасен и эффективен.

Если у вас слишком много параметров для этого, используйте динамический SQL - вы можете сгенерировать свой динамический SQL в хранимой процедуре или ранее, просто не забудьте избежать SQL injection issues.

Ваша проблема очень похожа на проблему dynamic search, покрытую Erland Sommarskog.

Производительность SQL Server создаст план выполнения для каждого возможного типа динамического запроса, так что производительность будет такой же хорошей, как наличие оператора IF для выбора каждого возможного оператора SQL.

Это резко контрастирует с использованием COLUMNB = CASE WHEN @COLUMNB IS NULL THEN COLUMNB ELSE @COLUMNB END, который будет иметь только один план выполнения и, следовательно, часто является плохим планом выполнения (в зависимости от вашего предложения и индексов в базе данных) и низкой производительности.

Смежные вопросы