【问题标题】:SQL Server and C# Master / Detail InsertSQL Server 和 C# 主/从插入
【发布时间】:2012-10-15 00:26:04
【问题描述】:

我正在创建将从我的 C# 应用程序调用的存储过程,并将主/详细信息输入 SQL Server。在 Header 表中,我将 TransactionId 作为 Identity 列,这样每次插入时我都会获得一个唯一的 ID。当我为详细信息表调用存储过程时,我想使用 Header 中的 PK ID 并将其插入到详细信息的 FK 中。确保我取回刚刚在 Header 表中创建的 ID 的最佳方法是什么?

CREATE TABLE [dbo].[Header835]
(
   [TRANSACTIONID] [int] IDENTITY(1, 1) NOT NULL
   , [FILENAME] [varchar](80) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
   , [TRADINGPARTNERNAME] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
   , [ISACRTL] [numeric](18, 0) NOT NULL
   , [STCRTL] [numeric](18, 0) NOT NULL
   , CONSTRAINT [PK_Header835] PRIMARY KEY CLUSTERED
   (
      [TRANSACTIONID] ASC
   ) WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]

【问题讨论】:

  • 我尝试从表中获取最大 ID( SET @TEMPTRANXID = (SELECT MAX(H.TRANSACTIONID) FROM [DB].[dbo].[HeaderTable] H))但我在想如果应用程序的不同实例对表进行多次调用,这可能并不总是有效。
  • 创建表 [dbo].[Header835]( [TRANSACTIONID] [int] IDENTITY(1,1) NOT NULL, [FILENAME] [varchar](80) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [TRADINGPARTNERNAME] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, [ISACRTL] [numeric](18, 0) NOT NULL, [STCRTL] [numeric](18, 0) NOT NULL, CONSTRAINT [PK_Header835] PRIMARY KEY CLUSTERED ([TRANSACTIONID] ASC )WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY]
  • 您是否允许用户多次使用相同的文件名?如果您以后需要对其进行审核,那可能会变得很糟糕。
  • 是的,但我正在考虑在每次处理文件名时为其添加时间戳。有什么建议吗?
  • 我不知道您现在正在使用的应用程序,但我认为允许用户上传相同的文件不是一个好主意,即使有时间戳也是如此。对于我的应用程序,我在他们上传文件时将文件保存到服务器,如果它已经存在则抛出错误,以便在审核时我们可以回顾并查看发送到应用程序的所有内容。

标签: c# sql-server stored-procedures transactions master-detail


【解决方案1】:

在 Header835 表中插入一条记录后,您将使用 SELECT @@IDENTITY 或 SELECT SCOPE_IDENTITY() 获得自动生成的 TransactionId 标识值,两者都将返回会话中最后一个自动生成的标识。 然后,您可以在详细记录的外键中使用此值。

【讨论】:

    【解决方案2】:

    查看我的博客文章,了解不同的方法以及此处的优缺点:

    http://sqlity.net/en/351/identity-crisis/

    简而言之,您希望您的代码如下所示:

    DECLARE @IdentValues TABLE(v INT);
    
    INSERT INTO [dbo].[Header835](<...  column list ...>) 
    OUTPUT INSERTED.[TRANSACTIONID] INTO @IdentValues(v)
    VALUES(<... value list ...>);
    
    SELECT v AS IdentityValues FROM @IdentValues;
    

    【讨论】:

    • 感谢您的回复。将来对我有用。
    【解决方案3】:

    你会想使用SCOPE_IDENTITY()

    DECLARE @headerTransactionId INT;
    
    INSERT INTO dbo.Header835(Filename, TradingPartnerName, IsACrtl, StCrtl)
    SELECT 'myFile.txt', 'Joe', 103, 123;
    
    SELECT @headerTransactionId = SCOPE_IDENTITY();    
    

    SQL Fiddle 示例

    【讨论】:

    • 感谢您的回答和向我介绍 sql fiddle。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    相关资源
    最近更新 更多