[SQL] 행이 존재하는 경우, 그렇지 않으면 삽입, 확인
SQL행이 존재하는 경우, 그렇지 않으면 삽입, 확인
나는 테이블의 행을 업데이트하는 T-SQL 저장 프로 시저를 작성해야합니다. 행이 존재하지 않는 경우, 삽입합니다. 트랜잭션 래핑이 모든 단계.
이 원자하고 신뢰할 수 있어야하기 때문에 이러한 현상이 예약 시스템입니다. 트랜잭션이 커밋과 비행 받았습니다 경우는 true를 반환해야합니다.
나는하지 있는지 @@ ROWCOUNT를 사용하는 방법에 대한, T-SQL에 새로운 해요. 이것은 내가 지금까지 쓴 것입니다. 나는 바른 길에 있습니까? 나는 확실히 당신을위한 쉬운 문제입니다.
-- BEGIN TRANSACTION (HOW TO DO?)
UPDATE Bookings
SET TicketsBooked = TicketsBooked + @TicketsToBook
WHERE FlightId = @Id AND TicketsMax < (TicketsBooked + @TicketsToBook)
-- Here I need to insert only if the row doesn't exists.
-- If the row exists but the condition TicketsMax is violated, I must not insert
-- the row and return FALSE
IF @@ROWCOUNT = 0
BEGIN
INSERT INTO Bookings ... (omitted)
END
-- END TRANSACTION (HOW TO DO?)
-- Return TRUE (How to do?)
해결법
-
==============================
1.MERGE 명령을 살펴보십시오. 당신은 UPDATE, INSERT 수행 및 하나 개의 문장에서 삭제할 수 있습니다.
MERGE 명령을 살펴보십시오. 당신은 UPDATE, INSERT 수행 및 하나 개의 문장에서 삭제할 수 있습니다.
다음은 MERGE를 사용하는 방법에 대한 작업 구현은 - 비행 다른, 업데이 트를 수행하기 전에 가득 삽입을 수행 여부를 확인합니다.
if exists(select 1 from INFORMATION_SCHEMA.TABLES T where T.TABLE_NAME = 'Bookings') begin drop table Bookings end GO create table Bookings( FlightID int identity(1, 1) primary key, TicketsMax int not null, TicketsBooked int not null ) GO insert Bookings(TicketsMax, TicketsBooked) select 1, 0 insert Bookings(TicketsMax, TicketsBooked) select 2, 2 insert Bookings(TicketsMax, TicketsBooked) select 3, 1 GO select * from Bookings
그리고 ...
declare @FlightID int = 1 declare @TicketsToBook int = 2 --; This should add a new record merge Bookings as T using (select @FlightID as FlightID, @TicketsToBook as TicketsToBook) as S on T.FlightID = S.FlightID and T.TicketsMax > (T.TicketsBooked + S.TicketsToBook) when matched then update set T.TicketsBooked = T.TicketsBooked + S.TicketsToBook when not matched then insert (TicketsMax, TicketsBooked) values(S.TicketsToBook, S.TicketsToBook); select * from Bookings
-
==============================
2.나는 각 항공편에 대해 하나의 행을 것 같은데요? 그렇다면:
나는 각 항공편에 대해 하나의 행을 것 같은데요? 그렇다면:
IF EXISTS (SELECT * FROM Bookings WHERE FLightID = @Id) BEGIN --UPDATE HERE END ELSE BEGIN -- INSERT HERE END
나는 10 티켓 최대가있는 경우는 새로운 행을 삽입하므로, 비행기를 초과 예약 할 수있는 일을 당신의 방법으로, 말을 가정하면 20을 예약하고 있습니다.
-
==============================
3.행의 존재 여부를 테스트 할 때 UPDLOCK, 노 걸이, HOLDLOCK 힌트를 전달합니다.
행의 존재 여부를 테스트 할 때 UPDLOCK, 노 걸이, HOLDLOCK 힌트를 전달합니다.
begin tran /* default read committed isolation level is fine */ if not exists (select * from Table with (updlock, rowlock, holdlock) where ...) /* insert */ else /* update */ commit /* locks are released here */
이미 존재하는 경우 UPDLOCK 힌트 힘은 쿼리가 커밋 또는 롤 다시 때까지 수정하는 다른 트랜잭션을 방지 행에 대한 업데이트 잠금을 촬영합니다.
HOLDLOCK 힌트 힘 쿼리는 커밋 또는 롤 다시 때까지 필터 기준과 일치하는 행을 추가하는 다른 거래를 방지 범위 잠금을 촬영합니다.
트랜잭션이 같은 페이지에 관련이없는 행을 업데이트하려고 다른 트랜잭션을 차단 (그러나 트레이드 오프 감소 된 경쟁과 증가 사이의 알 수 없습니다 그래서 노 걸이 힌트 힘은, 대신 기본 페이지 수준의 행 레벨로 세분화 잠금 잠금 오버 헤드 - 당신은) 하나의 트랜잭션에서 행 수준 잠금 많은 수의 복용하지 않도록해야합니다.
자세한 내용은 http://msdn.microsoft.com/en-us/library/ms187373.aspx를 참조하십시오.
트란을 시작 호출하는 것은 당신에게 당신이 그것에 도착하기 전에 뭔가에 잠금을 곤란 다른 트랜잭션에 대한 면역을 제공하지 않습니다 - 잠금 그들이 실행되는 걸릴 문으로 촬영합니다. 당신은 (초기 출시, 후반 획득) 가능한 한 빨리 트랜잭션을 커밋하여 최단 시간에 대한 잠금을 보유로 SQL을 시도하고 요소해야한다.
하여 PK가 BIGINT 경우 SQL 서버의 내부 해시는 64 비트 값 (다른 키 값이 동일한 로크 ID로 해싱 수 있음)에 대한 축퇴 같이 행 레벨 잠금 덜 효과적 일 수 있음을 유의해야한다.
-
==============================
4.난 내 솔루션을 쓰고 있어요. 또는 '병합'가 '내 방법은 서 있지 않습니다. 내 방법은 간단합니다.
난 내 솔루션을 쓰고 있어요. 또는 '병합'가 '내 방법은 서 있지 않습니다. 내 방법은 간단합니다.
INSERT INTO TableName (col1,col2) SELECT @par1, @par2 WHERE NOT EXISTS (SELECT col1,col2 FROM TableName WHERE col1=@par1 AND col2=@par2)
예를 들면 :
INSERT INTO Members (username) SELECT 'Cem' WHERE NOT EXISTS (SELECT username FROM Members WHERE username='Cem')
설명:
(1) SELECT COL1, COL2 TABLENAME FROM WHERE COL1 = @ PAR1 AND COL2 = @ PAR2 그것은 TABLENAME 값을 검색으로부터 선택
존재합니다 WHERE (2) @ PAR1, @ PAR2를 선택 하지 (1) 서브 쿼리에서 존재하는 경우는 소요
(3)에 삽입 TABLENAME (2) 단계 값
-
==============================
5.나는 마지막으로 이미 다음과 같은 모델을 사용하여, 존재하지 않는 것을 조건으로, 행을 삽입 할 수 있었다 :
나는 마지막으로 이미 다음과 같은 모델을 사용하여, 존재하지 않는 것을 조건으로, 행을 삽입 할 수 있었다 :
INSERT INTO table ( column1, column2, column3 ) ( SELECT $column1, $column2, $column3 WHERE NOT EXISTS ( SELECT 1 FROM table WHERE column1 = $column1 AND column2 = $column2 AND column3 = $column3 ) )
난에서 발견되는 :
http://www.postgresql.org/message-id/87hdow4ld1.fsf@stark.xeocode.com
-
==============================
6.이것은 내가 최근에해야 할 일을했을 뭔가 :
이것은 내가 최근에해야 할 일을했을 뭔가 :
set ANSI_NULLS ON set QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[cjso_UpdateCustomerLogin] ( @CustomerID AS INT, @UserName AS VARCHAR(25), @Password AS BINARY(16) ) AS BEGIN IF ISNULL((SELECT CustomerID FROM tblOnline_CustomerAccount WHERE CustomerID = @CustomerID), 0) = 0 BEGIN INSERT INTO [tblOnline_CustomerAccount] ( [CustomerID], [UserName], [Password], [LastLogin] ) VALUES ( /* CustomerID - int */ @CustomerID, /* UserName - varchar(25) */ @UserName, /* Password - binary(16) */ @Password, /* LastLogin - datetime */ NULL ) END ELSE BEGIN UPDATE [tblOnline_CustomerAccount] SET UserName = @UserName, Password = @Password WHERE CustomerID = @CustomerID END END
-
==============================
7.당신은 달성하기 위해 병합 기능을 사용할 수 있습니다. 그렇지 않으면 당신은 할 수 있습니다 :
당신은 달성하기 위해 병합 기능을 사용할 수 있습니다. 그렇지 않으면 당신은 할 수 있습니다 :
declare @rowCount int select @rowCount=@@RowCount if @rowCount=0 begin --insert....
-
==============================
8.전체 솔루션 (커서 구조를 포함) 이하입니다. 에 대한 카시우스 Porcus에 많은 감사 ... 트랜스 시작 위의 게시물에서 코드를 커밋합니다.
전체 솔루션 (커서 구조를 포함) 이하입니다. 에 대한 카시우스 Porcus에 많은 감사 ... 트랜스 시작 위의 게시물에서 코드를 커밋합니다.
declare @mystat6 bigint declare @mystat6p varchar(50) declare @mystat6b bigint DECLARE mycur1 CURSOR for select result1,picture,bittot from all_Tempnogos2results11 OPEN mycur1 FETCH NEXT FROM mycur1 INTO @mystat6, @mystat6p , @mystat6b WHILE @@Fetch_Status = 0 BEGIN begin tran /* default read committed isolation level is fine */ if not exists (select * from all_Tempnogos2results11_uniq with (updlock, rowlock, holdlock) where all_Tempnogos2results11_uniq.result1 = @mystat6 and all_Tempnogos2results11_uniq.bittot = @mystat6b ) insert all_Tempnogos2results11_uniq values (@mystat6 , @mystat6p , @mystat6b) --else -- /* update */ commit /* locks are released here */ FETCH NEXT FROM mycur1 INTO @mystat6 , @mystat6p , @mystat6b END CLOSE mycur1 DEALLOCATE mycur1 go
-
==============================
9.
INSERT INTO [DatabaseName1].dbo.[TableName1] SELECT * FROM [DatabaseName2].dbo.[TableName2] WHERE [YourPK] not in (select [YourPK] from [DatabaseName1].dbo.[TableName1])
-
==============================
10.이 문제에 대한 가장 좋은 방법은 먼저 데이터베이스 컬럼 UNIQUE를하고있다
이 문제에 대한 가장 좋은 방법은 먼저 데이터베이스 컬럼 UNIQUE를하고있다
ALTER table_name 테이블의 ADD UNIQUE KEY
THEN INSERT가 중복 키를 초래하는 경우 값이 삽입되지 않습니다 INTO를 TABLE_NAME 무시 / 테이블에 이미 존재한다.
-
==============================
11.
INSERT INTO table ( column1, column2, column3 ) SELECT $column1, $column2, $column3 EXCEPT SELECT column1, column2, column3 FROM table
from https://stackoverflow.com/questions/639854/check-if-a-row-exists-otherwise-insert by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] OPTION (RECOMPILE)는 항상 빠른입니다; 왜? (0) | 2020.04.03 |
---|---|
[SQL] 단일 쿼리에 삽입 여러 행에 대한 MySQL의 ON DUPLICATE KEY의 UPDATE (0) | 2020.04.03 |
[SQL] 실생활의 예를 들어, 때 OUTER / CROSS는 SQL에 적용 사용 (0) | 2020.04.02 |
[SQL] SQL 데이터베이스 설계에 대한 초보자 가이드 [마감] (0) | 2020.04.02 |
[SQL] 하나의 SQL 문에 모든 테이블, 저장 프로 시저, 트리거, 제약 및 모든 종속성을 드롭 (0) | 2020.04.02 |