Sybase-Sql-Anywhere

SQLAnywhere:呼叫函式的語法錯誤;沒有 IF 構造的呼叫正在工作

  • August 7, 2014

我有這個小程式碼範例,我在其中呼叫了一個帶有 4 個參數的過程:

DECLARE @tmp BIT
SET @tmp = 0
IF @tmp = 1
   call __insert_to_notifications_table('foo', '1234', '5678', 'Some comment')
ELSE
   print 'Path, which is choosen'

執行這個時,我得到

Syntaxerror at 'call' in line 4
SQLCODE=-131, ODBC 3-Status="42000"

如果我跑

call __insert_to_notifications_table('foo', '1234', '5678', 'Some comment')

直接,它工作正常。(該過程實際上是在開頭使用雙 __ 呼叫的;重命名時也不起作用)

像這樣執行程式碼時:

DECLARE @tmp BIT
SET @tmp = 0
IF @tmp = 1
   print 'other path'
ELSE
   print 'Path, which is choosen'

它似乎工作。因此,我會將問題歸結為電話呼叫。

我在這裡做錯了什麼?

我認為這是由於 Watcom-SQL 和 T-SQL 語法之間的混淆造成的。

因為您在第一個範例中使用 CALL(而不是 EXEC),所以數據庫引擎將假定程式碼在 Watcom SQL 中。(稍後會有 PRINT 聲明,但在此之前會做出決定)。

在第二個範例中,命令 PRINT 僅在 T-SQL 中有效,並且整個程式碼段都是有效的 T-SQL,因此數據庫引擎將假定所有程式碼都是 T-SQL 並且不需要 THEN。

如果我是對的,那麼這應該可以工作(在 Watcom-SQL 中未經測試):

DECLARE @tmp BIT;
SET @tmp = 0;
IF @tmp = 1
  THEN  call __insert_to_notifications_table('foo', '1234', '5678', 'Some comment')
ELSE
   MESSAGE 'Path, which is chosen' TO CLIENT
END IF;

有關各種 SQL 方言的 SQL Anywhere 支持的差異,請參見:http ://dcx.sybase.com/index.html#1200/en/dbusage/ug-sql-compat.html


更新 - 此批次在 dbISQL 中執行良好:

BEGIN
 DECLARE @tmp BIT;
 SET @tmp = 0;
 IF @tmp = 1
      THEN call dbo.sa_info()
 ELSE
     MESSAGE 'Path, which is chosen' TO CLIENT
 END IF;
END

(我添加了 BEGIN 和 END 來為 DECLARE 提供上下文並使用內置過程而不是您的使用者定義的過程)在 10.0.1.4310 和 16.0.0.1535 中測試。如果我省略 THEN,我會得到與你得到的相同的錯誤。

純 T-SQL 版本將是:

BEGIN
 DECLARE @tmp BIT
 SET @tmp = 0
 IF @tmp = 1
  EXEC dbo.sa_info
 ELSE
  PRINT 'Path, which is choosen'
END

這也適用於 10.0.1.4310 和 16.0.0.1535。不要忘記,如果您使用 T-SQL EXEC,則必須單獨指定參數(而不是在括號中):

[ EXECUTE ] | [ EXEC ][ @return_status = ] [creator.]procedure_name [ argument, ... ]
argument :
[ @parameter-name = ] expression
| [ @parameter-name = ] @variable [ output ]

引用自:https://dba.stackexchange.com/questions/73194