Ошибки с объявленными значениями переменных массива / таблицы в SAP HanaDB SQL - PullRequest
0 голосов
/ 29 мая 2020

Я пытаюсь добавить объявленную переменную, чтобы заменить жестко запрограммированный список значений в предложении «где в». Изучая, как Hana обрабатывает переменные массива, кажется, что я могу сделать это, объявив массив, а затем либо используя выбор непосредственно на нем, либо сначала отключив его в таблице, но я продолжаю получать ошибки, которые не могу решить. * Когда я пытаюсь сделать это таким образом:

DO
BEGIN

  DECLARE CODES_ARRAY NVARCHAR(100) ARRAY = ARRAY('01','02','03','04');

  SELECT T0."ItemCode"
  FROM OITM T0
    INNER JOIN OITW T1 ON T0."ItemCode" = T1."ItemCode"
  WHERE "WhsCode" IN (SELECT "code" FROM :CODES_ARRAY); -- line 9 where error occurs

END;

Я получаю это сообщение об ошибке sql syntax error: incorrect syntax near ")": line 9 col 54 (at pos 239)

Я не могу понять, каково разрешение синтаксической ошибки.

Итак, я попытался вставить объявленную табличную переменную следующим образом:

DO
BEGIN

  DECLARE CODES_ARRAY NVARCHAR(100) ARRAY = ARRAY('01','02','03','04');
  DECLARE CODES_TABLE TABLE = UNNEST(:CODES_ARRAY) AS ("code"); -- line 5 where error occurs

  SELECT T0."ItemCode"
  FROM OITM T0
    INNER JOIN OITW T1 ON T0."ItemCode" = T1."ItemCode"
  WHERE "WhsCode" IN (SELECT "code" FROM CODES_TABLE); -- I know : is missing here but when adding, the same error from previous block shows up

END;

и получил следующее сообщение об ошибке: identifier must be declared: 1: line 5 col 38 (at pos 123)

Насколько я могу судить, переменная массива объявлена ​​должным образом, поэтому я не знаю, как устранить ошибку.

Я прочитал справочную документацию SAP Hana SQL (для переменных массива / таблицы, функции unnest и т. д. c.) Снова и снова, и мне кажется, что я все настроил правильно, но не могу понять эти ошибки. Я хотел бы иметь возможность использовать оба этих подхода в разное время, если это возможно (подходы «переменная массива в переменную таблицы» и «только переменная массива»)

Я точно не знаю, что происходит здесь, но я заметил, что два разных сообщения об ошибках, упомянутые в моем сообщении (см. отличие от ошибок в первых двух блоках кода), заключаются в том, что каждая ошибка возникает либо непосредственно перед использованием переменной с : ( в случае UNNEST) или сразу после переменной с : (в случае использования в SELECT * FROM в запросе).

Из-за этого я задавался вопросом, является ли проблема «восходящей» на уровне Hana ADO.NET подготовки запроса приложения и уровня вызова выполнения, но я провел тест, и когда я дважды проверил строку запроса непосредственно перед ее выполнением , он выглядит без изменений, а переменные с : по-прежнему выглядят так, как должны, поэтому, по крайней мере, непосредственно перед выполнением через Hana ADO.NET HanaCommand он выглядит правильно - но после выполнения запроса с использованием HanaDataReader или HanaDataAdapter он возвращает упомянутые выше сообщения об ошибках. Может быть отвлекающим маневром преследовать проблему с уровня Hana ADO.NET, но я не знаю, что еще делать.

Обновить

Для дальнейшего устранения неполадок я попытался выполнить этот блок кода ниже, используя hdbsql.exe -n XXX.XXX.XXX.XXX:30015 -u XXX -p XXX -m -I "c:\temp\test.sql" -c "#", и он работает! Итак, ошибки, которые я вижу, появляются только при выполнении того же запроса через интерфейс Hana ADO.NET.

DO
BEGIN

  DECLARE CODES_ARRAY NVARCHAR(10) ARRAY = ARRAY('01','02','03','04');
  DECLARE CODES_TABLE TABLE ("code" NVARCHAR(10)) = UNNEST(:CODES_ARRAY) AS ("code");

  SELECT T0."ItemCode"
  FROM OITM T0
    INNER JOIN OITW T1 ON T0."ItemCode" = T1."ItemCode"
  WHERE "WhsCode" IN (SELECT "code" FROM :CODES_TABLE); -- line 10 where error occurs when using Hana ADO.NET

END;
#

Вышеупомянутое не удается, когда через Hana ADO.NET появляется сообщение об ошибке: sql syntax error: incorrect syntax near ")": line 10 col 54 (at pos 325), но работает при выполнении через hdbsql.

Обновление

Код C#, который выполняет запрос, довольно прост, но для полноты усилий по устранению неполадок я включил интересные части нашего класса HanaHelper. Этот код успешно работает, выполняя сотни запросов в день без ошибок и проблем. Это первая попытка объявления или использования в запросе переменной любого типа с помощью этого кода и когда начали появляться ошибки. Насколько я могу судить, проблема связана с использованием : при использовании переменной в запросе.

public class HanaHelper
{
    public HanaConnection objConn = null;

    public HanaHelper(string ConnectionString)
    {
        try
        {
            objConn = new HanaConnection(ConnectionString);
        }
        catch (Exception e)
        {
            Console.WriteLine(@"Exception thrown by HanaConnection: {0}\n{1}", e.Message, e.InnerException);
        }
    }

    public DataSet GetData(string strSQL)
    {
        using (HanaCommand objCmd = new HanaCommand(strSQL, objConn))
        {
            using (HanaDataAdapter objDA = new HanaDataAdapter(objCmd))
            {
                DataSet objDS = new DataSet();
                try
                {
                    objDA.Fill(objDS);
                }
                catch (Exception)
                {
                    throw;
                }
                finally 
                {
                  // do something interesting regardless of success or failure
                }
                objConn.Close();
                return objDS;
            }
        }
    }
}

Любая подсказка здесь, почему тот же запрос работает через hdbsql, но не работает при выполнении через Hana ADO.NET?

Обновление

Я понял, как использовать HanaSQLTrace в коде C#, чтобы я мог проверить подготовленный текст запроса и альт, источник ошибки сообщения становятся очевидными, все вхождения ":VARNAME" заменяются "? " (? заменяет : и пробел для каждого символа в имени переменной). Я предполагаю, что он пытается предварительно заменить вхождения : на ?, как если бы были параметры, которые нужно заменить.

Как можно отключить это поведение, поработать или обойти его, чтобы я мог эффективно использовать переменные в запросе в Hana ADO.NET?

1 Ответ

0 голосов
/ 30 мая 2020

Обновлено на основе обратной связи OP.

Чтобы ссылаться на переменную (чтобы получить доступ к ее значениям) в SQLScript, необходимо поставить двоеточие : в перед именем переменной.

Однако основной проблемой оказывается объявление табличной переменной CODES_TABLE. В HANA 2 SPS 4 сообщение об ошибке:

`SAP DBTech JDBC: [264]: invalid datatype: unknown type SYSTEM.TABLE: line 5 col 23`

Это указывает на объявление типизированной переменной TABLE CODES_TABLE, в которой отсутствует определение столбцов, которые должны быть в таблице.

Добавление этого исправляет проблему.

С этими изменениями ваш код должен работать:

DO
BEGIN

  DECLARE CODES_ARRAY NVARCHAR(100) ARRAY = ARRAY('01','02','03','04');
  DECLARE CODES_TABLE TABLE ("code" NVARCHAR(100)) = UNNEST(:CODES_ARRAY) AS ("code"); 
  --                        ^^^^^^^^^^^^^^^^^^^^^^
  --                                     |
  ---------------------------------------+

  SELECT 
        T0."ItemCode"
  FROM 
               OITM T0
    INNER JOIN OITW T1 
      ON T0."ItemCode" = T1."ItemCode"
  WHERE 
        "WhsCode" IN (SELECT "code" FROM :CODES_TABLE);
  --                                     ^
  --                                     |
  ---------------------------------------+
END;

Альтернативный вариант объявления и назначения табличной переменной - не использовать команду DECLARE.

DO
BEGIN

  DECLARE CODES_ARRAY NVARCHAR(100) ARRAY = ARRAY('01','02','03','04');

  CODES_TABLE = UNNEST(:CODES_ARRAY) AS ("code"); 

  SELECT 
        T0."ItemCode"
  FROM 
               OITM T0
    INNER JOIN OITW T1 
      ON T0."ItemCode" = T1."ItemCode"
  WHERE 
        "WhsCode" IN (SELECT "code" FROM :CODES_TABLE);

END;
...