在我的SQL Server 2008数据库中,我有许多具有相同结构的不同表。我在不同的存储过程中查询它们。我的第一个尝试是将表名传递给存储过程,如:
CREATE PROCEDURE MyTest
@tableName nvarchar(255)
AS
BEGIN
SELECT * FROM @tableName
END
但我们不能在SQL中使用表名参数。 So I asked you并尝试使用同义词而不是表名的参数来解决方案:
CREATE PROCEDURE MyTest
@tableName nvarchar(255)
AS
BEGIN
EXEC SetSimilarityTableNameSynonym @tbl = @tableName;
SELECT * FROM dbo.CurrentSimilarityTable
END
SetSimilarityTableNameSynonym是一个SP,用于将同义词dbo.CurrentSimilarityTable设置为传递的值(特定的表名)。它看起来像:
CREATE PROCEDURE [dbo].[SetSimilarityTableNameSynonym]
@tbl nvarchar(255)
AS
BEGIN
IF object_id('dbo.CurrentSimilarityTable', 'SN') IS NOT NULL
DROP SYNONYM CurrentSimilarityTable;
-- Set the synonym for each existing table
IF @tbl = 'byArticle'
CREATE SYNONYM dbo.CurrentSimilarityTable FOR dbo.similarity_byArticle;
...
END
现在,正如您可能看到的那样,问题在于并发访问SP,这将“破坏”彼此分配的同义词。所以我尝试通过NewID()
为GUID的每个单个SP调用创建动态同义词DECLARE @theGUID uniqueidentifier;
SET @theGUID=NEWID()
SET @theSynonym = 'dbo.SimTabSyn_' + CONVERT(nvarchar(255), @theGUID);
但是......我无法使用动态创建的名称来创建同义词:
CREATE SYNONYM @theSynonym FOR dbo.similarity_byArticle;
不起作用。
有人有想法,如何让动态同义词运行?这甚至可能吗?
提前致谢, 弗兰克
答案 0 :(得分:1)
我建议的是在动态SQL中运行CREATE SYNONYM。这也意味着您的代码以相当高的权限运行(db_owner
或ddl_admin
)。在保护代码时,您可能需要EXECUTE AS OWNER
来允许它。
你最终会为同一张桌子找到多少个同义词?如果你必须这样做,我会使用OBJECT_ID而不是NEWID并先测试,这样每个表就有一个同义词。
但是如果每个表都有一个同义词,那么为什么不使用表名??
对于同一个表创建一个或多个同义词有什么意义,因为表名已经是唯一的......
我修复了数据库设计。
答案 1 :(得分:0)
为什么您希望多个并发用户覆盖单个资源(同义词)? 如果您的MyTest过程将表名作为参数,为什么不简单地执行动态SQL?您可以针对允许此过程选择的硬编码表列表或针对sys.tables
来验证@tableName。