仅使用提供的字段的T-SQL匹配过程

时间:2014-06-30 20:59:01

标签: stored-procedures sql-server-2000 matching

我正在尝试编写一个存储过程,以根据客户提供给我们的信息,将医生列表与我们数据库中的现有记录进行匹配。目前我们使用MS Access基于给定的标识符手动加入,但是这个过程往往是单调乏味且过于耗时,因此需要自动化它。

我要做的是创建一个临时表,其中包含可能匹配的所有列,然后使用字段作为连接条件运行一系列匹配查询以使我们的标识符返回。

例如,可用的匹配字段是Name,NPI,MedicaidNum和DOB,所以我会这样写:

UPDATE Temp
SET Temp.RECID = Phy.RECID
FROM TempTable Temp
INNER JOIN Physicians Phy
ON Phy.Name = Temp.Name
AND Phy.NPI = Temp.NPI
AND Phy.MedicaidNum = Temp.MedicaidNum
AND Phy.DOB = Temp.DOB

UPDATE Temp
SET Temp.RECID = Phy.RECID
FROM TempTable Temp
INNER JOIN Physicians Phy
ON Phy.Name = Temp.Name
AND Phy.NPI = Temp.NPI
AND Phy.MedicaidNum = Temp.MedicaidNum
WHERE Temp.RECID IS NULL

...etc

问题在于可能提供大约15种不同的标识符,而客户通常只提供每个记录集3或4个标识符。因此,在考虑空值的情况下,可能需要编写一百多个不同的查询以仅匹配六个提供的字段。

我在想,可能有一种方法可以传入一个变量(或变量)来指示实际为数据集提供哪些列,然后编写动态连接语句和/或where子句,但我不知道知道这是否适用于T-SQL。类似的东西:

DECLARE @Field1
DECLARE @Field2
....
UPDATE Temp
SET Temp.RECID = Phy.RECID
FROM TempTable Temp
INNER JOIN Physicians Phy
ON Phy.@Field1 = Temp.@Field1
AND Phy.@Field2 = Temp.@Field2

这样我会限制我需要编写的查询数量,只需要担心我匹配的字段数量,而不是担心哪些特定的字段。或许对这个问题有更好的解决方法吗?

1 个答案:

答案 0 :(得分:0)

你可以这样做,但要注意这种方法非常容易出现SQL注入。这只是为了说明如何做这样的事情的原则。我告诉你你想用它做什么。对于这段代码,我让proc取三个字段:

CREATE PROC DynamicUpdateSQLFromFieldList   @Field1 VARCHAR(50) = NULL,
                                            @Field2 VARCHAR(50) = NULL,
                                            @Field3 VARCHAR(50) = NULL,
                                            @RunMe BIT = 0
AS
BEGIN

DECLARE @SQL AS VARCHAR(1000);

    SELECT  @SQL = 'UPDATE Temp
                    SET Temp.RECID = Phy.RECID  
                    FROM TempTable Temp
                    INNER JOIN Physicians Phy ON ' +
                    COALESCE('Phy.' + @Field1 + ' = Temp.' + @Field1 + ' AND ', '') +
                    COALESCE('Phy.' + @Field2 + ' = Temp.' + @Field2 + ' AND ', '') +
                    COALESCE('Phy.' + @Field3 + ' = Temp.' + @Field3, '') + ';';

    IF @RunMe = 0               
        SELECT @SQL AS SQL;
    ELSE
        EXEC(@SQL)

END

我添加了一个调试模式标志,以便您可以在不想运行它的情况下查看SQL。因此,例如,如果您运行:

EXEC DynamicUpdateSQLFromFieldList @field1='col1', @field2='col2', @field3='col3'

EXEC DynamicUpdateSQLFromFieldList @field1='col1', @field2='col2', @field3='col3', @RunMe=0

生成的SQL将是:

UPDATE Temp
SET Temp.RECID = Phy.RECID
FROM TempTable Temp INNER JOIN Physicians Phy
ON Phy.col1 = Temp.col1 AND
   Phy.col2 = Temp.col2 AND
   Phy.col3 = Temp.col3;

如果您运行此行:

EXEC DynamicUpdateSQLFromFieldList @field1='col1', @field2='col2', @field3='col3', @RunMe=1

它将执行更新。如果您希望它更安全,可以将传入的字段名称列入sys表白名单,以确保在执行任何代码之前列中实际存在列。