【发布时间】:2015-05-26 21:07:27
【问题描述】:
我们目前正在构建一个 Web 门户,以便能够查看我们组织的 SQL 报告。目前,该门户使用 PHP 脚本和 MS SQLSRV 驱动程序来查询我们众多的 SQL 数据库。本质上,门户通过调用我们创建的返回请求数据的存储过程来工作。然后,该网站解析数据并向用户提供他们请求的信息。此流程适用于我们所有现有的报告,除了我目前正在努力制作的报告。
有问题的存储过程/报告使用用户定义的表类型最终在脚本末尾创建 WHERE IN 类型子句,以便根据提供的帐号进行选择。
我很痛苦地意识到 SQLSRV 驱动程序不支持通过用户定义的表类型发送,因此我有一个工作函数,它接受一个 CSV 格式的输入字符串并返回一个包含数据的表。这部分有效,我可以将一串帐号传递给它,它成功地将它们解析成单独的行。如果我远程调用它,我会得到预期的结果。如果我提供 4 个帐号,我的表格会填满 4 行。
输入字符串的一个例子是:
A00000000001,A00000000002,A00000000003,A00000000004
如果我从 MS SQL Server Management Studio 手动运行此脚本/存储过程并为其提供相同的字符串,则该脚本/存储过程可以正常工作;按预期提供的每个帐号给我一行。我还可以从 Mgmt Studio 手动运行脚本,并将字符串硬编码到脚本中,我得到的结果相同,表明脚本可以正常工作。但问题是,当远程执行存储过程时,只返回最后一行,并且它始终是字符串/转换表中的最后一个帐号。更糟糕的是,如果我运行 SQL Trace Profiler,我可以看到正在发出的请求,我可以看到它正在将我的帐号插入到我的表类型中,并且对发送过来的每个帐户都这样做,但是当 Trace Profiler 显示实际存储过程,只返回一行...
我原以为问题出在我的 PHP 脚本中,但看到跟踪分析器也只捕获一行,这让我觉得远程运行时存储过程发生了一些事情......
这是一个精简版的 SQL,没有所有字段以节省空间:
USE [Livendb]
GO
/****** Object: StoredProcedure [dbo].[cejnsqip] Script Date: 05/25/2015 12:24:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[cejnsqip] @acctList varchar(MAX)
AS
--Split our comma separated list that was sent over so we can convert it to an array
DECLARE @acctNumList acctNum_list_tbltype
INSERT INTO @acctNumList(AccountNumber) SELECT Data FROM [dbo].[cejSplitCommaList](@acctList, ',') -- Call to function to split csv into table
SELECT
...
...
...
FROM AbstractData
WHERE AbstractData.AccountNumber IN(SELECT AccountNumber FROM @acctNumList)
【问题讨论】:
标签: php sql sql-server stored-procedures sqlsrv