如何在Yardi7-Voyager中处理参数为ID列表或SQL查询的筛选
解决Yardi7-Voyager中单条SELECT语句兼容两种参数类型的问题
我完全理解你的困境——Yardi系统限制只能提交单条SELECT语句,但你的参数既可能是逗号分隔的ID列表,又可能是动态SELECT查询字符串,而SQL函数里又没法执行动态SQL。下面几个方案可以尝试解决这个问题:
方案一:使用OPENROWSET处理动态查询(需服务器配置)
这个方案能把两种情况整合到单条SELECT里,通过判断参数内容分支处理。需要先让管理员配置SQL Server允许Ad Hoc分布式查询:
-- 仅需执行一次的配置(需管理员权限) sp_configure 'show advanced options', 1; RECONFIGURE; sp_configure 'Ad Hoc Distributed Queries', 1; RECONFIGURE;
然后用这条单SELECT语句即可:
SELECT ...columns... FROM ...tables and joins... WHERE -- 处理逗号分隔的ID列表 ( CHARINDEX('SELECT', @p, 1) = 0 AND CHARINDEX('select', @p, 1) = 0 AND HMY IN ( SELECT CONVERT(NUMERIC(18, 0), strval) FROM dbo.StringSplit(REPLACE(@p, '''', ''), ',') ) ) OR -- 处理动态SELECT查询 ( CHARINDEX('SELECT', @p, 1) > 0 OR CHARINDEX('select', @p, 1) > 0 AND HMY IN ( SELECT ID -- 替换成你的动态查询返回的实际列名 FROM OPENROWSET( 'SQLNCLI', 'Server=' + @@SERVERNAME + ';Trusted_Connection=yes;', @p ) AS queryResults ) )
注意事项:
- 确保服务器上已安装
SQLNCLI驱动,且当前用户拥有执行OPENROWSET的权限 - 如果你的动态SELECT查询返回的列名不是
ID,一定要修改子查询中的对应列名 - 这种方式存在一定安全风险,要确保参数@p的内容是可信的,避免SQL注入
方案二:创建存储过程,通过OPENROWSET调用
如果Yardi允许调用存储过程的结果,可以先把你的逻辑封装成存储过程,再用单条SELECT获取结果:
首先创建存储过程:
CREATE PROCEDURE dbo.GetYardiFilteredRecords @p NVARCHAR(MAX) AS BEGIN SET NOCOUNT ON; DECLARE @property NVARCHAR(MAX) = REPLACE(@p, '''', ''); DECLARE @propList TABLE (hproperty NUMERIC(18, 0)); IF CHARINDEX('SELECT', @property) > 0 OR CHARINDEX('select', @property) > 0 BEGIN INSERT INTO @propList EXEC sp_executesql @property; END ELSE BEGIN INSERT INTO @propList SELECT CONVERT(NUMERIC(18, 0), strval) FROM dbo.StringSplit(@property, ','); END -- 替换成你的实际业务查询 SELECT ...columns... FROM ...tables and joins... WHERE ...filters... AND HMY IN (SELECT hproperty FROM @propList); END
然后用这条单SELECT语句调用存储过程:
SELECT * FROM OPENROWSET( 'SQLNCLI', 'Server=(local);Trusted_Connection=yes;', 'EXEC YourDatabaseName.dbo.GetYardiFilteredRecords @p=''' + REPLACE(@p, '''', '''''') + '''' ) AS procResults
方案三:分情况编写两个查询
如果Yardi系统可以根据@p的内容自动选择执行哪个查询,可以准备两个版本的查询:
- 当@p是逗号分隔的ID列表时:
SELECT ...columns... FROM ...tables and joins... WHERE ...filters... AND HMY IN ( SELECT CONVERT(NUMERIC(18, 0), strval) FROM dbo.StringSplit(REPLACE(@p, '''', ''), ',') )
- 当@p是动态SELECT查询时:
EXEC sp_executesql N' SELECT ...columns... FROM ...tables and joins... WHERE ...filters... AND HMY IN (' + @p + N')'
这个方案需要调用方能够判断@p是否包含SELECT关键字,然后切换对应的查询执行。
内容的提问来源于stack exchange,提问作者Eray Balkanli
相关产品推荐
相关产品推荐

