Процедура БД для динамического обновления столбцов БД - PullRequest
0 голосов
/ 29 января 2019

Требуется обновить в столбце БД только те столбцы, которые редактируются из внешнего интерфейса.Логика, которую я использую, состоит в том, чтобы отправить 2 массива из кода Java в процедуру БД.

1-й массив: Column_array, который содержит имена столбцов, которые должны быть обновлены.

&

2-й массив: value_array, который содержит значения столбцов, относящиеся к column_array.

От JAVA:

Array value_array = ((OracleConnection) dbConnection).createOracleArray("STRING_ARRAY",
                valueList.toArray());

        Array param_array = ((OracleConnection) dbConnection).createOracleArray("STRING_ARRAY",
                            paramList.toArray());

 stmt = dbConnection.prepareCall(SqlConstants.UPDATE_SUBSCRIBER_CONFIG_IN_BOLTES);//
            stmt.setLong(1, 3628);
            stmt.setLong(2, 3629);
            stmt.setLong(3, 3632);
            stmt.setArray(4, param_array);
            stmt.setArray(5, value_array);
            int count = stmt.executeUpdate();

СЕЙЧАС на стороне БД:

как я могу выполнить эту итерациюсписок, чтобы обновить и установить это в предложении SET ???

 PROCEDURE update_subscriber_config (
    p_app_id        VARCHAR2,
    p_service_id     VARCHAR2,
    p_pubsub_id       VARCHAR2,
    column_list     string_array,
    value_list      string_array
)
    AS
BEGIN

FOR a IN 1..column_list.count LOOP
        update  bolt_oracle_pubsub_config set 
            column_list(a)=value_list(a),
             ...how to do iteration here???

      where  APP_ID = p_app_id AND SERVICE_ID =  p_service_id AND PUBSUB_ID = p_pubsub_id;
       END LOOP;

END update_subscriber_config;

ПОЖАЛУЙСТА, ПОМОГИТЕ.

Ответы [ 3 ]

0 голосов
/ 29 января 2019

Возможно, вы могли бы попытаться избежать одного из массивов, которые являются массивом столбцов, поскольку Oracle SQL допустил бы, если значение равно нулю.

Ниже приведен псевдокод.

PROCEDURE update_subscriber_config (p_app_id             VARCHAR2,
                                    p_service_id         VARCHAR2,
                                    p_pubsub_id          VARCHAR2,
                                    p_first_column       VARCHAR2,
                                    p_second_column      VARCHAR2,
                                    --column_list     string_array,
                                    i_array           IN my_array_type)
AS
BEGIN
   FORALL i IN 1 .. i_array.COUNT
      UPDATE bolt_oracle_pubsub_config
         SET your_first_column =
                TREAT (i_array (i) AS my_array_type).column_array_name,
             your_second_column =
                TREAT (i_array (i) AS my_array_type).second_column_array_name
       WHERE     APP_ID = p_app_id
             AND SERVICE_ID = p_service_id
             AND PUBSUB_ID = p_pubsub_id;

END update_subscriber_config;

Если какой-либо из столбцов, указанных в обновлении SQL, пуст, он будет нулевым или пустым в таблице после выполнения обновления.Сказав это, убедитесь, что заполнены все NOT NULL или обязательные столбцы.

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

0 голосов
/ 29 января 2019

Я нашел решение, которое было проще, чем итерация массива.

Решение - использовать метод COALESCE.

 PROCEDURE TEST (
      p_app_id       NUMBER,
    p_service_id   NUMBER,
    p_pubsub_id    NUMBER,
    p_pubsub_name       VARCHAR2,
    p_host              VARCHAR2,
    p_user_name           VARCHAR2,
    p_auth_key              VARCHAR2
)
    AS
BEGIN

     update bolt_elastic_pubsub_config set 
      PUBSUB_NAME = coalesce(p_pubsub_name, PUBSUB_NAME),
       HOST = coalesce(p_host, HOST),
        USER_NAME = coalesce(p_user_name, USER_NAME),
        AUTH_KEY = coalesce(p_auth_key, AUTH_KEY)
     where  APP_ID = p_app_id AND SERVICE_ID =  p_service_id AND PUBSUB_ID = p_pubsub_id;

END TEST;
0 голосов
/ 29 января 2019

Вы должны использовать динамический SQL для сборки сделанных на заказ операторов обновления.Это будет выглядеть примерно так:

PROCEDURE update_subscriber_config (
    p_app_id        VARCHAR2,
    p_service_id     VARCHAR2,
    p_pubsub_id       VARCHAR2,
    column_list     string_array,
    value_list      string_array
)
AS
   stmt varchar2(32767);
BEGIN

    stmt := 'update  bolt_oracle_pubsub_config set ';

    FOR a IN 1..column_list.count LOOP
        if a != 1 then
           stmt := stmt ||', ';
        end if;
        stmt := stmt || column_list(a) ||'=''' ||value_list(a)||'''';
       END LOOP;

       stmt := stmt ||
             ' where  APP_ID = :p1 AND SERVICE_ID = :p2 AND PUBSUB_ID = :p3';
      execute immediate stmt using p_app_id , p_service_id , p_pubsub_id;
END update_subscriber_config;

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

Динамический SQL сложен, поскольку он превращает ошибки компиляции в ошибки времени выполнения.В вашем случае у вас есть фрагмент кода, который потенциально выполняет разные операторы обновления каждый раз, когда вы вызываете его.Поэтому тестирование этой процедуры - настоящий кошмар.Это означает, что у вас есть сильная зависимость от внешнего интерфейса, передающего массивы с допустимым содержимым.

...