Errors with declared array/table variable values in SAP HanaDB SQL

*爱你&永不变心* 提交于 2021-01-05 07:35:40

问题


I am trying to add a declared variable to replace a hardcoded list of values in a "where in" clause. Researching how Hana handles array variables it seems like I can do this by declaring an array and then either using a select directly on it or by unnesting it first into a table but I keep getting errors I can't resolve.

When I try it this way:

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;

I get this error message sql syntax error: incorrect syntax near ")": line 9 col 54 (at pos 239)

I can't figure out what the syntax error resolution is.

So then I tried inserting a declared table variable like this:

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;

and I get this error message: identifier must be declared: 1: line 5 col 38 (at pos 123)

As far as I can tell the array variable is declared as it should be so I don't know how to resolve the error.

I've read the SAP Hana SQL Reference documentation (for array/table variables, unnest function, etc.) over and over and it seems like I've got everything setup correctly but can't figure out these errors. I would like to be able to use both of these approaches at different times if possible (the "array variable to table variable" and the "array variable only" approaches)

I don't know exactly what is going on here, but one thing I notice that the two different error messages referenced in my post (see difference from errors in the first two code blocks) is that each error is occurring either immediately before the use of the variable with the : (in the case of the UNNEST) or immediately following the variable with the : (in the case of using in the SELECT * FROM in the query).

Because of that, I wondered if the issue is "upstream" at the Hana ADO.NET application query preparation and execution call level, but I ran a test and when I double checked the query string just before it is executed, it appears unchanged and the variables with : still look as they should, so at least as far as just before execution through Hana ADO.NET HanaCommand it looks correct - but once executing the query using HanaDataReader or HanaDataAdapter it returns the error messages referred to above. It may be a red herring to chase the problem from the Hana ADO.NET level but don't know what else to do.

Update

To further troubleshoot, I tried executing this code block below using hdbsql.exe -n XXX.XXX.XXX.XXX:30015 -u XXX -p XXX -m -I "c:\temp\test.sql" -c "#" and it works! So, the errors I see only show up when executing the same query through the Hana ADO.NET interface.

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;
#

The above fails when through Hana ADO.NET with the error message: sql syntax error: incorrect syntax near ")": line 10 col 54 (at pos 325) but works when executed through hdbsql.

Update

The C# code that executes the query is fairly straight forward, but for completeness of troubleshooting effort I am including the interesting parts of our HanaHelper class. This code works successfully to execute 100s of queries a day without errors or problems. This is the first time where a variable of any type has been attempted to be declared or used in a query through this code and when the errors started showing up. As far as I can tell, the issue is tied to the use of the : when using the variable in the query.

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;
            }
        }
    }
}

Any clue here why the same query works through hdbsql but fails when executing through Hana ADO.NET?

Update

I figured out how to use HanaSQLTrace in the C# code so that I can inspect the prepared query text and viola, the source of error messages becomes apparent, all occurrences of ":VARNAME" are replaced with "? " (a ? replaces the : and a space for each character in the variable name). I suppose it is trying to pre-substitute occurrences of : with a ? as if there were parameters to be substituted.

How can this behavior be disabled, or worked with, or worked around so that I can use variables in a query in Hana ADO.NET effectively?


回答1:


Updated based on the OP feedback.

To refer to a variable (in order to access its value(s)) in SQLScript it's necessary to put a colon : in front of the variable name.

The main issue, however, turns out to be the declaration of the CODES_TABLE table variable. With HANA 2 SPS 4 the error message is

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

This points to the declaration of the TABLE typed variable CODES_TABLE which lacks the definition of what columns should be in the table.

Adding this fixes the issue.

With these changes, your code should work:

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;

An alternative option to declare and assign the table variable is to not use the DECLARE command.

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;


来源:https://stackoverflow.com/questions/62091343/errors-with-declared-array-table-variable-values-in-sap-hanadb-sql

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!