【发布时间】:2017-12-29 18:27:34
【问题描述】:
我需要在远程主机上的 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 警告:odbc_exec():SQL 错误:[FreeTDS][SQL 服务器]找不到“dbo”列或用户定义的列 函数或聚合“dbo.__WeightCalculation”,或 名称有歧义。,SQL 状态 37000 在 SQLExecDirect 中 /var/www/web/test/odbc.php 第 14 行
除此之外,我还尝试使用 DECLARE EXEC SELECT 执行该函数,该函数在 SQL Studio 中也可以正常工作,但不是通过 CLI 或 PHP。
需要单独绑定参数和执行函数吗?非常感谢任何有关如何通过 PHP 执行 MSSQL 用户定义函数的提示(因为 CLI 仅用于测试/验证)。
请注意:
- 函数调用显然只是更大查询的一部分
- 实际场景/用例是 Magento CE 1.9.x 的产品导入(约 20k 产品),使用 MAGMI 在远程服务器上进行 odbc 连接的能力。然而,根据 MAGMI 的 wiki,这需要将整个语句放在单个 .sql 文件中(由于到目前为止这不起作用,我开始深入挖掘并遇到上述基本问题,因此我决定在这里而不是在magento.stackexchange.com)
- 创建函数、在 SQL Studio 中运行查询以及通过 ODBC 连接的用户是相同的,即 sa
【问题讨论】:
-
您是否使用与创建函数相同的用户帐户运行。也许 dbo 不对。
-
嘿@John Kane - 是的,我错过了那个信息。我是 SQL Studio 和通过 ODBC 连接的远程服务器上的同一个用户,即 sa (我知道,使用该用户不是最好的主意,但这就是我从远程服务器管理员那里得到的全部内容,所以远)
-
@ChristophFarnleitner,确保数据库上下文与 SSMS 相同。
-
嘿@DanGuzman - 我认为这是不可能的 - 或者我没有完全理解你的意思。如果我创建像 CREATE FUNCTION [dbname].dbo.functionname() 这样的函数,我会得到“'CREATE / ALTER FUNCTION',数据库名称不能指定为对象名称的前缀。”作为一个错误
-
问题的一个常见原因是使用不带引号的混合大小写标识符,因为某些工具会引用包装这些标识符,导致
WeightCalculationvsweightcalculationvsWEIGHTCALCULATION,没有一个匹配其他。也就是说,您可能会发现{[?=]call procedure-name[([parameter][,[parameter]]...)]} +的 MSDN 文档很有帮助。
标签: php sql-server-2012 odbc user-defined-functions isql