首页 文章

使用动态sql查询更新表

提问于
浏览
1

对于项目,我们使用包含所有文本的表(名为 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

    是的,可以在SQL Server 2005中引入synonym mechanism的帮助 . 因此,您可以在设置过程中根据 ProjectSettings 表中的数据创建同义词,并且可以在函数中使用它 . 您的代码看起来像这样:

    UPDATE: 函数代码在这里被注释,因为它仍然包含动态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
    */
    

    UPDATE 这是解决问题的又一次尝试 . 现在它使用了一些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

  • 0

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

相关问题