【问题标题】:Merge two tables into one table in sql serversql server 将两张表合并为一张表
【发布时间】:2018-01-09 08:43:57
【问题描述】:

我有这些架构:

CREATE TABLE Ndc
(
    [NdcId] INT NOT NULL PRIMARY KEY IDENTITY(1,1), 
    [Code] VARCHAR(256) NULL,
)

CREATE TABLE [RxCui]
(
    [RxCuiId] INT NOT NULL PRIMARY KEY IDENTITY(1,1), 
    [Code] VARCHAR(256) NULL, 
)

CREATE TABLE [RxCuiNdc]
(
    [RxCuiNdcId] INT NOT NULL PRIMARY KEY IDENTITY(1,1), 
    [RxCuiId] INT NOT NULL, 
    [NdcId] INT NOT NULL,
    CONSTRAINT [FK_RxCuiNdc_Ndc] FOREIGN KEY (NdcId) REFERENCES Common.Ndc(NdcId), 
    CONSTRAINT [FK_RxCuiNdc_RxCui] FOREIGN KEY (RxCuiId) REFERENCES Common.RxCui(RxCuiId), 
)

我有一个 JSON,它是一个药物标签列表,每个标签都与两个字符串数组相关联。一个数组表示 RxCui 列表,另一个表示 Ndc 列表。我将获取 JSON 文件并将每个 RxCui 插入到 RxCui 表中,并将 Ndc 表中的每个 Ndc 从上面的模式中插入。假设这些表包含所有 Ndc 和 RxCui 并且没有任何重复项,那么我想将这些映射到 RxCuiNdc 表。

这是代表 JSON 的类

public class DrugLabel
    {
        public OpenFda openfda { get; set; }
    }

public class OpenFda
    {
        public IList<string> product_ndc { get; set; } = new List<string>();
        public IList<string> rxcui { get; set; } = new List<string>();
    }

public class DrugLabels
    {
        public List<DrugLabel> results { get; set; } = new List<DrugLabel>();
    }

我尝试了一个存储过程来创建 RxCui 和 Ndc 之间的映射。

CREATE PROCEDURE MapRxCuiToNdc
    @rxCuiList varchar(MAX),
    @ndcList varchar(MAX)
AS
    DECLARE @rxCuiTable TABLE (RxCuiCode varchar(max)) 

    -- Insert statement
    INSERT INTO @rxCuiTable
    SELECT Value
    FROM  string_split(@rxCuiList, ',')  

    DECLARE @ndcTable TABLE (NdcCode varchar(max)) 

    -- Insert statement
    INSERT INTO @ndcTable
    SELECT Value
    FROM  string_split(@ndcList, ',')  

    MERGE INTO [Common].[RxCuiNdc] T
       USING (SELECT A.RxCuiId, A.Code AS RxCuiCode, B.NdcId, B.Code AS NdcCode
                FROM Common.RxCui A cross join Common.Ndc B
                WHERE A.Code IN (SELECT RxCuiCode FROM @rxCuiTable) AND B.Code IN (SELECT NdcCode FROM @ndcTable )
            ) S
          ON T.RxCuiId = S.RxCuiId AND T.NdcId = S.NdcId
    WHEN MATCHED THEN 
       UPDATE
          SET T.NdcId = S.NdcId, T.RxCuiId = S.RxCuiId
    WHEN NOT MATCHED THEN
       INSERT ( NdcId, RxCuiId ) VALUES ( S.NdcId, S.RxCuiId);

我遇到的问题是获取正确的映射。在我的 C# 代码中,我试图找到一种方法来发送每个 RxCui 和 Ndc 的列表,而不必对每个标签进行 foreach。

我目前拥有的是这个

var data = new DrugLabels();
var productsNdc = data.results.Where(x => x.openfda?.product_ndc?.Count > 0).SelectMany(x => x.openfda.product_ndc).ToArray();
var rxCui = data.results.Where(x => x.openfda?.rxcui?.Count > 0).SelectMany(x => x.openfda.rxcui).ToArray();
await MedicationSearchStoredProcedure(string.Join(",", rxCui), string.Join(",", productsNdc));

前面的代码将存储过程映射到每个 rxCui 和我发送的每个 Ndc。我想要的是根据标签映射它们,我能想到的唯一方法是使用 foreach,类似这样。

foreach(var label in data.results)
{
    await MedicationSearchStoredProcedure(string.Join(",", label.openfda.rxcui), string.Join(",", label.openfda.product_ndc));
}

但那是我不想做的。

有什么建议吗? foreach 是唯一的方法吗?

【问题讨论】:

  • “在我的 C# 代码中,我试图找到一种方法来发送每个 RxCui 和 Ndc 的列表,而不必对每个标签进行 foreach。”为什么?我根本不会为此使用存储过程。我只是直接从 C# 代码插入行。如果您担心数据一致性或网络效率,可以将它们打包在事务中。
  • 当您的意思是发送时,我假设您正在执行 INSERT 查询或 UPDATE 查询。每当您将数据存储到数据库中时,您都需要指定 WHERE。 WHERE 需要是数据库的单行或数据库的多行。如果您忽略 WHERE,数据库的每一行都将使用相同的值进行更新。所以你需要有一个循环,所以每个新项目都有一个唯一的 WHERE 来指定行。另一种选择是创建一个执行循环的存储过程。

标签: c# sql json sql-server database-schema


【解决方案1】:

我建议您获取一个结果数组,然后拨打电话。

List<string> rxcui = new List<string>();
List<string> product_ndc = new List<string>();

foreach(var label in data.results)
{
    rxcui.AddRange(string.Join(",", label.openfda.rxcui));
    product_ndc.AddRange(string.Join(",", label.openfda.product_ndc));
}

await MedicationSearchStoredProcedure(rxcui, product_ndc);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 2014-06-26
    • 2016-01-16
    相关资源
    最近更新 更多