SQL Server中的动态表

时间:2017-09-21 13:30:50

标签: sql-server stored-procedures

我有一个非常奇怪和复杂的要求,我需要帮助。我有一张表,让我们说Tasks包含用户/系统的所有任务。我需要过滤掉每个用户的任务并在UI中显示它。但是这里是场景,Tasks表包含一列base_table,用于存储它所基于的表名(真实SQL Server表)。它还存储导航到基表中特定记录的base table id。现在我需要在基表中添加一些过滤器,如果它满足,则会检索任务。

我确实尝试建立一个程序,该程序会针对基表点击选择查询并检查条件。

CREATE PROCEDURE gautam_dtTable_test 
    (@TableName AS nvarchar(max))
AS 
BEGIN try 
    declare @sql nvarchar(max)
    declare @ret tinyint

    set @ret = 0
    set @sql = 'select 1 where exists (Select top 1 Id from ' + @TableName+' where some_condition)';

    Exec sp_executesql @sql, N'@var tinyint out', @ret out

    return @ret
end try
begin catch
    return 0
end catch

我已经使用过程输入表名并命中一些条件并返回一个标志,1/0种东西。我也想使用try catch,这样如果有任何错误,它将返回false。

这就是我使用过程而不是功能的原因。但似乎我们可以将此过程用于sql语句。总的来说,我的想法是

Select * 
from tasks 
where some_conditions 
  and procedure/function_to_check(tasks.base_table)

我的方法的关键问题

  1. base_table名称可能无效,其中包含一些列。所以,我很想使用try-catch。
  2. 需要将其作为子查询嵌入以避免并行操作。但是当你的程序/功能定义了 EXEC sp_executesql 时,这似乎很难。
  3. 感谢任何形式的帮助。提前谢谢!

1 个答案:

答案 0 :(得分:0)

陈述的问题有点不清楚,所以我将在这里做一些假设。看起来您正在尝试实现以下目标:

首先,您似乎只是尝试在任务表中返回'base_table'列值引用有效SQL Server表的任务。

其次,如果我正确理解帖子,基于传递给tasks表的where子句条件,您将尝试确定基表中是否存在相同的列。

第一部分肯定是可行的。但是,第二部分不是因为它要求查询以某种方式解析自己以确定正在过滤哪些列。 以下查询显示如何仅检索存在有效对应表的任务。

SELECT      *
FROM        [dbo].[tasks] ts
CROSS APPLY (
                SELECT [name] 
                FROM sys.objects WHERE object_id = OBJECT_ID('[dbo].' + QUOTENAME(ts.base_table)) AND type in (N'U')
            ) tb

如果您尝试过滤的字段是预先知道的(即您没有尝试根据任务表进行解析),那么您可以修改上述查询以传递要检查的所需列遵循:

DECLARE @columnNameToCheck NVARCHAR(50) = 'col2'

SELECT      ts.*
FROM        [dbo].[tasks] ts
CROSS APPLY (
                SELECT [name] 
                FROM sys.objects WHERE object_id = OBJECT_ID('[dbo].' + QUOTENAME(ts.base_table)) AND type in (N'U')
            ) tb
CROSS APPLY (
                SELECT [name] 
                FROM sys.columns WHERE object_id = OBJECT_ID('[dbo].' + QUOTENAME(ts.base_table)) AND [name] = @columnName