在 PHP 中执行 MSSQL 用户定义函数

execute MSSQL user-defined function in PHP

我需要在远程主机上的 PHP 中执行用户定义的函数(通过 odbc)。

函数本身是一个简单的计算,已在 MS SQL Server Studio 中创建,如下所示:

CREATE FUNCTION dbo.__WeightCalculation(@_Length float, @_Width float, @_Height float, @_ShapeType nvarchar(255)) 
RETURNS float AS 

BEGIN
    return (select 
        (CASE
            WHEN @_ShapeType  = 'A'
            THEN (((@_Width * @_Height * 0.5) / 100) * @_Length) / 1000 
            WHEN @_ShapeType IN ('B', 'C', 'D', 'E') 
            THEN (((@_Width * @_Height * 0.75) / 100) * @_Length) / 1000 
            ELSE 'nA'
        END) as THIS_WEIGHT)
END;

我已经能够通过执行

验证此函数是否正常工作并返回预期结果
select dbo.__WeightCalculation(10, 20, 30, 'A');


----------------------
0,03

(1 Zeile(n) betroffen)

在管理工作室中。

但是,除此之外,我无法以任何其他方式执行此功能。

当尝试 运行 通过网络服务器上的 CLI 运行该功能时,即

user@server:~/tmp# isql dsn usr pwd
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> select dbo.__WeightCalculation(10, 20, 30, 'A');
[ISQL]ERROR: Could not SQLExecute
SQL>

会提示[ISQL]ERROR: Could not SQLExecute。 当尝试 运行 从 PHP 脚本运行该功能时,即

$connect = odbc_connect($dsn, $user, $pw);
$query = "SELECT dbo.__WeightCalculation(10, 20, 30, 'A')";
$result = odbc_exec($connect, $query);
$row = odbc_fetch_array($result);
echo '<pre>';
print_r($row);
echo '</pre>';

...可以在服务器错误日志中找到以下内容:

mod_fcgid: stderr: PHP Warning: odbc_exec(): SQL error: [FreeTDS][SQL Server]Cannot find either column "dbo" or the user-defined function or aggregate "dbo.__WeightCalculation", or the name is ambiguous., SQL state 37000 in SQLExecDirect in /var/www/web/test/odbc.php on line 14

除此之外,我尝试使用 DECLARE EXEC SELECT 执行函数,它在 SQL Studio 中也按预期工作,但不是通过 CLI或 PHP.

需要分别绑定参数和执行函数吗?非常感谢有关如何通过 PHP 执行 MSSQL 用户定义函数的任何提示(因为 CLI 仅适用于 testing/verifying)。

请注意:

  1. 函数调用显然只是更大查询的一部分
  2. 实际 scenario/use-case 是 Magento CE 1 的产品导入(~20k 产品)。9.x 使用 MAGMI 在远程服务器上进行 odbc 连接的能力。根据 MA​​GMI 的 wiki,这需要将整个语句放在一个 .sql 文件中(因为到目前为止这没有用,我开始深入挖掘并遇到上述基本问题,因此我决定 post 我的问题在这里而不是 magento.stackexchange.com)
  3. 创建函数的用户,运行在SQLStudio 中查询和通过ODBC 连接的用户相同,即sa

好吧,有一次它击中了你,对吧? ;)

我的函数,因为没有另外指定,是在数据库中创建的 master。事实上,我无法告诉您是否总是如此(至少当您以 sa 身份登录时)- 如果有人能回答这个问题,可能会很有趣。

但是,为特定 table 创建函数的最初想法(我认为,@DanGuzman 在某些时候也考虑到了这一点?)是正确的,就像我所做的那样,是错误的,即 --

CREATE FUNCTION [databasename].dbo.functionname(@params)
  ...
GO

-- 不起作用,而 --

USE [databasename];
GO
CREATE FUNCTION dbo.functionname(@params)
  ...
GO

-- 确实。