행이 있는지 확인하고, 그렇지 않으면 삽입
테이블의 행을 업데이트하는 T-SQL 저장 프로시저를 작성해야 합니다.행이 존재하지 않으면 행을 삽입합니다.이 모든 단계는 트랜잭션으로 마무리됩니다.
이것은 예약 시스템용이기 때문에 원자적이고 신뢰할 수 있어야 합니다.트랜잭션이 커밋되고 항공편이 예약되면 true를 반환해야 합니다.
잘 있습니다.@@rowcount지금까지 써온 글입니다.가가 올올 을을 을?? ???
-- 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?)
각 비행편마다 한 줄씩 있는 것 같아요?이 경우:
IF EXISTS (SELECT * FROM Bookings WHERE FLightID = @Id)
BEGIN
--UPDATE HERE
END
ELSE
BEGIN
-- INSERT HERE
END
제가 말씀드린 대로, 당신의 방법은 항공권을 10장까지 예약하고 20장을 예약했을 때 새로운 열을 삽입하기 때문에 초과 예약을 할 수 있습니다.
MERGE 명령어를 확인합니다.할수있습니다UPDATE,INSERT&DELETE일문일답으로
은 '사용하다'의 입니다.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
행의 존재를 테스트할 때 updlock, rowlock, 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 힌트를 사용하면 쿼리가 강제로 범위 잠금을 수행하므로 사용자가 커밋하거나 롤백할 때까지 다른 트랜잭션에서 필터 기준과 일치하는 행을 추가할 수 없습니다.
rowlock 힌트는 기본 페이지 수준이 아닌 행 수준으로 잠금 세분화를 강제합니다.따라서 트랜잭션은 동일한 페이지에서 관련 없는 행을 업데이트하려는 다른 트랜잭션을 차단하지 않습니다(단, 경합 감소와 잠금 오버헤드 증가 간의 트레이드오프에 유의하십시오. 단일 트랜잭션에서 다수의 행 수준 잠금을 사용하지 마십시오).
상세한 것에 대하여는, http://msdn.microsoft.com/en-us/library/ms187373.aspx 를 참조해 주세요.
잠금은 잠금이 실행되는 문이 실행될 때 사용됩니다. begin tran을 호출하면 다른 트랜잭션에 대한 잠금이 발생하기 전에 차단되지 않습니다.가능한 한 빨리 트랜잭션을 커밋하여 가능한 한 짧은 시간 동안 잠금이 유지되도록 SQL을 계수화해야 합니다(늦은 취득, 빠른 릴리스).
행 수준 잠금은 PK가 bigint인 경우 SQL Server의 내부 해시가 64비트 값으로 저하되므로 효과가 떨어질 수 있습니다(키 값이 다르면 동일한 잠금 ID로 해시될 수 있음).
난 해결책을 쓰고 있어. 내 방법은 'if'나 'fil'이 아니야. 내 방법은 쉬워.
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) col1, col2 FROM TableName WHERE col1=@par1 AND col2=@par2 TableName 검색값에서 선택한다.
(2) (1) 서브쿼리에서 @par1, @par2 WHERE NOT EXISTES 를 선택합니다.존재하지 않는 경우는, 취득합니다.
(3) TableName (2) 스텝 값을 삽입합니다.
다음 모델을 사용하여 존재하지 않는 조건으로 행을 삽입할 수 있었습니다.
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@http.xeocode.com
최근에 제가 해야 할 일이 있습니다.
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
Merge Function을 사용하여 수행할 수 있습니다.그렇지 않으면 다음을 수행할 수 있습니다.
declare @rowCount int
select @rowCount=@@RowCount
if @rowCount=0
begin
--insert....
INSERT INTO [DatabaseName1].dbo.[TableName1] SELECT * FROM [DatabaseName2].dbo.[TableName2]
WHERE [YourPK] not in (select [YourPK] from [DatabaseName1].dbo.[TableName1])
전체 솔루션은 아래에 나와 있습니다(커서 구조 포함).카시우스 포르쿠스 덕분에begin trans ... commit위의 게시물에서 나온 코드.
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
T1에서 T2로 데이터를 복사하여 T2에서 중복을 방지하는 간단한 방법
--Insert a new record
INSERT INTO dbo.Table2(NoEtu, FirstName, LastName)
SELECT t1.NoEtuDos, t1.FName, t1.LName
FROM dbo.Table1 as t1
WHERE NOT EXISTS (SELECT (1) FROM dbo.Table2 AS t2
WHERE t1.FName = t2.FirstName
AND t1.LName = t2.LastName
AND t1.NoEtuDos = t2.NoEtu)
INSERT INTO table ( column1, column2, column3 )
SELECT $column1, $column2, $column3
EXCEPT SELECT column1, column2, column3
FROM table
이 문제에 대한 최선의 접근법은 먼저 데이터베이스 열을 고유하게 만드는 것입니다.
ALTER TABLE table_name ADD UNIQUE KEY
THEN INSERT IGNORE INTO table_name테이블 내에 중복 키 또는 중복 키가 존재하는 경우 값은 삽입되지 않습니다.
언급URL : https://stackoverflow.com/questions/639854/check-if-a-row-exists-otherwise-insert
'programing' 카테고리의 다른 글
| index match는 공백 셀에 대해 0을 반환합니다. "-"로 해야 합니다. (0) | 2023.04.11 |
|---|---|
| PowerShell: 단일 명령어 환경 변수 설정 (0) | 2023.04.11 |
| ID_인 경우 'table' 테이블의 ID 열에 대한 명시적 값을 삽입할 수 없습니다.INSERT가 OFF로 설정되었습니다. (0) | 2023.04.06 |
| SQL Management Studio에서 다른 포트 번호를 지정하려면 어떻게 해야 합니까? (0) | 2023.04.06 |
| SQL 뷰에 파라미터를 전달할 수 있습니까? (0) | 2023.04.06 |