You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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的内容自动选择执行哪个查询,可以准备两个版本的查询:

  1. 当@p是逗号分隔的ID列表时:
SELECT ...columns...
FROM ...tables and joins...
WHERE ...filters... AND HMY IN (
    SELECT CONVERT(NUMERIC(18, 0), strval)
    FROM dbo.StringSplit(REPLACE(@p, '''', ''), ',')
)
  1. 当@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:37:49