在存储过程SQL Server中的Select查询中执行动态查询

时间:2019-12-14 07:08:44

标签: sql-server stored-procedures dynamicquery

我正在尝试执行动态生成的选择查询作为Select语句的列值。我尝试使用函数,但不允许执行动态查询块。

谁能找到我想要的解决方案?

create table #temp(column1 nvarchar(10), column2 nvarchar(10), column3 nvarchar(10));
insert into #temp exec fetch_some_data;

select 
columnX, 
columnY,
(select COALESCE('column3', null) from #temp a where coalesce('a.column1', null) = 'somevalue') as columnZ
from TableName

P.S .: #temp的此列不固定,它们是通过读取csv动态创建的。只是为了说明,它们被添加了

1 个答案:

答案 0 :(得分:0)

  

我尝试使用函数,但不允许执行动态查询   

您处在正确的轨道上。您不能使用普通的tsql函数(exec查询限制),但是可以使用标量clr函数。

操作方法

https://docs.microsoft.com/en-us/sql/relational-databases/clr-integration-database-objects-user-defined-functions/clr-scalar-valued-functions?view=sql-server-ver15#example-of-a-clr-scalar-valued-function上查看clr函数的示例

对于执行动态语句,示例代码可以是:

using Microsoft.SqlServer.Server;
using System.Data.SqlClient;

public class T
{
    [SqlFunction(DataAccess = DataAccessKind.Read)]
    public static object ExecDynamicSql(string sql)
    {
        using (SqlConnection conn
            = new SqlConnection("context connection=true"))
        {
            conn.Open();
            SqlCommand cmd = new SqlCommand(sql, conn);
            return cmd.ExecuteScalar();
        }
    }
}

将其编译为dll(使用Visual Studio或csc.exe)

然后用ssms:

CREATE ASSEMBLY DynamicSqlAssembly   
FROM 'C:\Users\..xyz...\Documents\Visual Studio xzy\Projects\xyz\xyz\bin\Debug\xyzname.dll'  --<-- path to dll here
WITH PERMISSION_SET = SAFE; 
GO

CREATE FUNCTION dbo.FnExecSql(@query nvarchar(max)) 
RETURNS sql_variant
WITH RETURNS NULL ON NULL INPUT
AS EXTERNAL NAME DynamicSqlAssembly.T.ExecDynamicSql;   
GO 


select dbo.FnExecSql('select getdate()');

select name, dbo.FnExecSql('select count(*) from ' + name) as tablecount
from sys.tables;

为完整起见,您可能希望向clr代码添加异常处理,并可能在发生异常时返回null。这取决于您的要求。