IDENTITY插入行的最佳方法是什么?
我知道@@IDENTITY和IDENT_CURRENT和SCOPE_IDENTITY,但不明白连接到每个利弊.
有人可以解释一下这些差异,以及何时应该使用它们?
灵感来自这个问题,对于SET NOCOUNT有不同的看法......
我们应该为SQL Server使用SET NOCOUNT ON吗?如果没有,为什么不呢?
它的作用编辑6,2011年7月22日
它会在任何DML之后抑制"xx行受影响"消息.这是一个结果集,当发送时,客户端必须处理它.它很小,但可以测量(见下面的答案)
对于触发器等,客户端将收到多个"受影响的xx行",这会导致某些ORM,MS Access,JPA等出现各种错误(参见下面的编辑)
背景:
一般接受的最佳实践(我想直到这个问题)是SET NOCOUNT ON在SQL Server中的触发器和存储过程中使用.我们在任何地方都使用它,快速谷歌显示大量的SQL Server MVP也同意.
MSDN表示这可能会破坏.net SQLDataAdapter.
现在,这对我来说意味着SQLDataAdapter仅限于完全简单的CRUD处理,因为它希望"n行受影响"消息匹配.所以,我不能用:
在问题marc_s(谁知道他的SQL的东西)说不要使用它.这与我的想法不同(我认为自己在SQL方面也有一定的能力).
有可能我错过了一些东西(随意指出明显的东西),但你们有什么想法呢?
注意:我看到这个错误已经好几年了,因为我现在不使用SQLDataAdapter.
在评论和问题后编辑:
编辑:更多想法......
我们有多个客户端:一个可以使用C#SQLDataAdaptor,另一个可以使用Java中的nHibernate.这些可能会以不同的方式受到影响SET NOCOUNT ON.
如果您将存储过程视为方法,那么假设某些内部处理以某种方式为您自己的目的而工作则是不好的形式(反模式).
编辑2:触发器打破nHibernate问题,SET NOCOUNT ON无法设置
(不,它不是一个重复的这个)
编辑3:更多信息,感谢我的MVP同事
编辑2011年5月13日
编辑2011年6月14日
使用表变量打破JPA,存储过程:JPA 2.0是否支持SQL Server表变量?
编辑6:2011年8月15日
SSMS"编辑行"数据网格需要SET NOCOUNT ON:使用GROUP BY更新触发器
编辑2013年3月7日7:07
来自@RemusRusanu的更深入的细节:
SET NOCOUNT …
返回的一些JDBC驱动程序的唯一方法Statement.RETURN_GENERATED_KEYS是执行以下操作:
long key = -1L;
Statement statement = connection.createStatement();
statement.executeUpdate(YOUR_SQL_HERE, Statement.RETURN_GENERATED_KEYS);
ResultSet rs = statement.getGeneratedKeys();
if (rs != null && rs.next()) {
key = rs.getLong(1);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法做同样的事情PreparedStatement?
编辑
我问我是否可以这样做的原因PreparedStatement考虑以下情况:
private static final String SQL_CREATE =
"INSERT INTO
USER(FIRST_NAME, MIDDLE_NAME, LAST_NAME, EMAIL_ADDRESS, DOB)
VALUES (?, ?, ?, ?, ?)";
Run Code Online (Sandbox Code Playgroud)
在USER表中有一个PRIMARY KEY (USER_ID)是BIGINT AUTOINCREMENT(因此你没有在SQL_CREATE字符串中看到它.
现在,我填充?使用PreparedStatement.setXXXX(index, value).我想回来ResultSet rs = PreparedStatement.getGeneratedKeys().我怎样才能做到这一点?
在使用存储过程的SQL Server中是否可以在表中返回一些值插入的表中的标识列值?例如,如果我们在表中插入数据,则使用存储过程:
表TBL
因此,如果我运行存储过程插入一些值,如:
Insert into TBL (Name, UserName, Password)
Values ('example', 'example', '$2a$12$00WFrz3dOfLaIgpTYRJ9CeuB6VicjLGhLset8WtFrzvtpRekcP1lq')
Run Code Online (Sandbox Code Playgroud)
如何返回UserID此插入的值.我需要UserID的值用于其他一些操作,任何人都可以解决这个问题吗?
我有一个表,我创建了一个INSTEAD OF触发器来强制执行一些业务规则.
问题是,当我将数据插入此表时,SCOPE_IDENTITY()返回一个NULL值,而不是实际插入的标识.
INSERT INTO [dbo].[Payment]([DateFrom], [DateTo], [CustomerId], [AdminId])
VALUES ('2009-01-20', '2009-01-31', 6, 1)
SELECT SCOPE_IDENTITY()
Run Code Online (Sandbox Code Playgroud)
CREATE TRIGGER [dbo].[TR_Payments_Insert]
ON [dbo].[Payment]
INSTEAD OF INSERT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF NOT EXISTS(SELECT 1 FROM dbo.Payment p
INNER JOIN Inserted i ON p.CustomerId = i.CustomerId
WHERE (i.DateFrom >= p.DateFrom AND i.DateFrom <= p.DateTo) OR (i.DateTo >= p.DateFrom …Run Code Online (Sandbox Code Playgroud) 我已经阅读了有关获取插入行的标识的问题.我的问题有点相关.
有没有办法获得插入行的guid?我正在使用的表有一个guid作为主键(默认为newid),我想在插入行后检索该guid.
有没有像什么@@IDENTITY,IDENT_CURRENT或者SCOPE_IDENTITY对的GUID?
我想简单地执行一个SQL查询,该查询将返回添加到表中的行的当前id,例如:
insert into V_Post output inserted._ID values('Please return the id of THIS row :)')
Run Code Online (Sandbox Code Playgroud)
那将返回一个像155的数字
所以我的问题的目的是将该数字存储在某种局部变量中,如XVALUE,然后在任何其他SQL查询中使用此XVALUE,如:
insert into V_Posts values(1, XVALUE, null, GETDATE(), null, null, 1)
Run Code Online (Sandbox Code Playgroud)
所以我想要的是:
int XVALUE = insert into V_Post output inserted._ID values('Please return the id of THIS row :)')
insert into V_Posts values(1, XVALUE, null, GETDATE(), null, null, 1)
Run Code Online (Sandbox Code Playgroud)
要么
insert into V_Posts values(1, insert into V_Post output inserted._ID values('Please return the id of THIS row :)'), null, GETDATE(), null, null, 1)
Run Code Online (Sandbox Code Playgroud)
但它都不起作用:(
我希望我能很好地解释我的问题,我真的非常感谢你的帮助.
编辑
请注意我有两个表:V_posts和V_post
如何在SQL Server中插入INSERT后获取id?
对于我的插页,我使用 context.ExecuteStoreCommand()
警告:我有一个多线程应用程序,它在同一个表中"同时"插入一些数据.
使用FireDac,如何在ms sql server上获取最后插入的id?谢谢
使用SQL Server 2012.我想在表中插入唯一的字符串.我总是希望返回唯一字符串的行ID.现在,这可以通过两种方式实现.
哪种解决方案最好?
这是有问题的表:
CREATE TABLE [dbo].[Comment](
[CommentID] [int] IDENTITY(1,1) NOT NULL,
[Comment] [nvarchar](256) NOT NULL
CONSTRAINT [PK_Comment] PRIMARY KEY CLUSTERED([CommentID] ASC)
)
CREATE UNIQUE NONCLUSTERED INDEX [IX_Comment_Comment] ON [dbo].[Comment]
(
[Comment] ASC
)
Run Code Online (Sandbox Code Playgroud)
解决方案1:
SELECT首先检查字符串是否存在.如果确实如此,请返回ID.否则,INSERT新行并返回新创建的ID.
CREATE PROCEDURE [dbo].[add_comment]
@Comment [nvarchar](256)
AS
BEGIN
SET NOCOUNT ON
DECLARE @CommentID [int]
DECLARE @TransactionCount [int]
BEGIN TRY
SET @TransactionCount = @@TRANCOUNT
IF @TransactionCount = 0
BEGIN TRANSACTION
SELECT @CommentID = [CommentID] FROM [dbo].[Comment] WHERE …Run Code Online (Sandbox Code Playgroud) 假设我有一个临时表,其中包含一些列,其中一个列专门用于插入发票的标识列,其他列用于插入发票数据本身。如下表:
CREATE TABLE #InvoiceItems
(
RowNumber INT, -- Used for inserting new invoice
SaleID INT, -- Used for inserting new invoice
BuyerID INT, -- Used for inserting new invoice
InvoiceID INT -- Intended for PK of the invoice added after inserting it
);
Run Code Online (Sandbox Code Playgroud)
我使用类似以下内容将数据插入发票表
INSERT INTO [Invoice]
SELECT [col1, ...]
FROM #InvoiceItems
Run Code Online (Sandbox Code Playgroud)
如何InvoiceID在使用临时表将表数据插入发票表时填充列?我了解SCOPE_IDENTITY()函数,但它仅返回最后插入的 PK,这并不真正适合我的需要。
我也可以使用 awhile来一一执行此操作,但由于我计划插入的数据量非常大,我觉得它不会是最优化的选项。
感谢您提前的答复。
sql-server ×9
sql ×7
t-sql ×3
identity ×2
insert ×2
ado.net ×1
anydac ×1
c# ×1
concurrency ×1
database ×1
delphi ×1
firedac ×1
java ×1
jdbc ×1
linq-to-sql ×1