使用动态sql查询更新表

时间:2014-08-26 15:40:48

标签: sql tsql sql-server-2005 stored-procedures

对于项目,我们使用包含所有文本的表(名为txtTable)。每列包含不同的语言(例如,列L9是英语,列L7是德语等。)。

TextID L9          L7               L16    L10    L12
------------------------------------------------------
26     Archiving   Archivierung     NULL   NULL   NULL
27     Logging     Protokollierung  NULL   NULL   NULL
28     Comments    Kommentar        NULL   NULL   NULL

此表位于Microsoft SQL Server 2005上的数据库中。最大的问题是每次重新启动程序时此数据库名称都会更改。这是此第三方程序的典型行为,无法更改。

此数据库旁边和同一服务器上是我们自己的数据库。在此数据库中有几个表,指向textID以正确语言生成报告数据(SQL Server Reporting Services)。此数据库还包含一个表"ProjectSettings",其中包含一些属性,如texttable数据库的名称,以及用于生成报告数据的存储过程。

我们现在通过更改数据库名称从此表中请求正确语言的正确文本的方式是创建动态SQL查询并在存储过程中执行它。

现在我们想知道是否有更简洁的方法来获得正确语言的文本。我们正在考虑使用textID创建一个函数,并将语言作为参数,但我们找不到一个好方法。我们考虑过一个函数,所以我们可以在select语句中使用它,但这不起作用:

CREATE FUNCTION [dbo].[GetTextFromLib]
(
    @TextID  int, 
    @LanguageColumn Varchar(5)
)
RETURNS varchar(255)
AS
BEGIN
    -- return variables
    DECLARE @ResultVar varchar(255)

    -- Local variables
    DECLARE @TextLibraryDatabaseName varchar(1000)
    DECLARE @nvcSqlQuery varchar(1000)  

    -- get the report language database name
    SELECT @TextLibraryDatabaseName = TextLibraryDatabaseName FROM ProjectSettings

    SET @nvcSqlQuery = 'SELECT @ResultVar =' + @LanguageColumn + ' FROM [' + @TextLibraryDatabaseName + '].dbo.TXTTable WHERE TEXTID = ' + cast(@TextID as varchar(30))

     EXEC(@nvcSqlQuery)

    -- Return the result of the function
    RETURN @ResultVar
END

有没有办法解决这个问题,所以我们不必在我们的存储过程中使用动态sql,所以它只包含在1个函数中?

提前致谢&亲切的问候,

库尔特

2 个答案:

答案 0 :(得分:0)

是的,可以在SQL Server 2005引入synonym mechanism的帮助下完成。因此,您可以在设置过程中根据ProjectSettings表中的数据创建同义词,并且可以在你的功能。您的代码将如下所示:

更新:此处对功能代码进行了评论,因为它仍然包含动态SQL,而Kurt在其评论中表示,它不起作用。新版本的功能低于此代码。

   
-- Creating synonym for TXTTable table
-- somewhere in code when processing current settings
-- Suppose your synonym name is 'TextLibrary'
--
-- Drop previously created synonym
IF  EXISTS (SELECT * FROM sys.synonyms WHERE name = N'TextLibrary')
DROP SYNONYM TextLibrary

-- Creating synonym using dynamic SQL

-- Local variables
DECLARE @TextLibraryDatabaseName varchar(1000)
DECLARE @nvcSqlQuery varchar(1000)  

-- get the report language database name
SELECT @TextLibraryDatabaseName = TextLibraryDatabaseName FROM ProjectSettings

SET @nvcSqlQuery = 'CREATE SYNONYM TextLibrary FOR [' + @TextLibraryDatabaseName + '].dbo.TXTTable'

EXEC(@nvcSqlQuery)

-- Synonym created  

/* UPDATE: This code is commented but left for discussion consistency
-- Function code
CREATE FUNCTION [dbo].[GetTextFromLib]
(
    @TextID  int, 
    @LanguageColumn Varchar(5)
)
RETURNS varchar(255)
AS
BEGIN
    -- return variables
    DECLARE @ResultVar varchar(255)

    -- Local variables
    DECLARE @nvcSqlQuery varchar(1000)  

    SET @nvcSqlQuery = 'SELECT @ResultVar =' + @LanguageColumn + ' FROM TextLibrary WHERE TEXTID = ' + cast(@TextID as varchar(30))

     EXEC(@nvcSqlQuery)

    -- Return the result of the function
    RETURN @ResultVar

END
*/

更新这是解决问题的又一次尝试。现在它使用了一些XML技巧:

   
-- Function code
CREATE FUNCTION [dbo].[GetTextFromLib]
(
    @TextID  int, 
    @LanguageColumn Varchar(5)
)
RETURNS varchar(255)
AS
BEGIN
    -- return variables
    DECLARE @ResultVar varchar(255)

    -- Local variables
    DECLARE @XmlVar XML 

    -- Select required record into XML variable
    -- XML has each table column value in element with corresponding name
    SELECT @XmlVar = ( SELECT * FROM TextLibrary
                       WHERE TEXTID = @TextID
                       FOR XML RAW, ELEMENTS )

    -- Select value of required element from XML
    SELECT @ResultVar = Element.value('(.)[1]', 'varchar(255)') 
    FROM @XmlVar.nodes('/row/*') AS T(Element)
    WHERE Element.value('local-name(.)', 'varchar(50)') = @LanguageColumn

    -- Return the result of the function
    RETURN @ResultVar

END

希望这有帮助。

在Stackoverflow上回答此问题的回答 - How to get node name and values from an xml variable in t-sql

答案 1 :(得分:0)

对我而言,这听起来像是一个完整的PITA ...然而,这个"单词"的数据库有多大?你正在处理。特别是如果它变化不大并且保持相当稳定。为什么不在某个正常周期(例如早上),只生成一个动态查询,查询更改并将其同步到标准"您的数据库中的表名称不会发生变化。然后,所有查询都针对您的版本运行,并且每次都完全删除常量动态查询。是的,需要运行这个同步存储过程,但是如果它可以按计划运行,那么你应该没问题,并且再次说明"单词"表的大小。适当的语言背景。