I tried using functions but that don't allow to execute dynamic query
block.
You are on the right track. You can not use a normal tsql function (exec query limitation) but you could use a scalar clr function.
How-to
Check the example of the clr function at https://learn.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
for executing a dynamic statement, the sample code could be:
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();
}
}
}
compile it to a dll (either with visual studio or csc.exe)
then in 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;
For completeness, you might want to add exception handling to the clr code and possibly return null when an exception occurs.It depends on your requirements.