존재하는 경우, 다른 삽입을 선택한 다음 선택
Microsoft SQL Server 2005에서는 다음을 어떻게 설명합니까?
IF EXISTS (SELECT * FROM Table WHERE FieldValue='') THEN
SELECT TableID FROM Table WHERE FieldValue=''
ELSE
INSERT INTO TABLE(FieldValue) VALUES('')
SELECT TableID FROM Table WHERE TableID=SCOPE_IDENTITY()
END IF
내가 하려는 것은 빈 필드 값이 이미 있는지 확인하고 해당 표를 반환하는 것입니다.ID를 입력하지 않으면 빈 필드 값을 삽입하고 해당 기본 키를 반환합니다.
트랜잭션에서 이 작업을 수행하여 두 클라이언트가 동일한 필드 값을 두 번 삽입하지 않도록 해야 합니다.
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
DECLARE @id AS INT
SELECT @id = tableId FROM table WHERE fieldValue=@newValue
IF @id IS NULL
BEGIN
INSERT INTO table (fieldValue) VALUES (@newValue)
SELECT @id = SCOPE_IDENTITY()
END
SELECT @id
COMMIT TRANSACTION
이중 체크 잠금을 사용하여 잠금 오버헤드를 줄일 수도 있습니다.
DECLARE @id AS INT
SELECT @id = tableID FROM table (NOLOCK) WHERE fieldValue=@newValue
IF @id IS NULL
BEGIN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT @id = tableID FROM table WHERE fieldValue=@newValue
IF @id IS NULL
BEGIN
INSERT INTO table (fieldValue) VALUES (@newValue)
SELECT @id = SCOPE_IDENTITY()
END
COMMIT TRANSACTION
END
SELECT @id
분리 레벨 직렬화가 필요한 이유에 대해 말하자면, 직렬화 가능한 트랜잭션 내부에 있을 때 테이블을 처음으로 치는 선택은 레코드가 있어야 하는 위치를 커버하는 범위 잠금을 생성하므로 이 트랜잭션이 끝날 때까지 다른 사용자가 동일한 레코드를 삽입할 수 없습니다.
분리 레벨 직렬화가 없으면 기본 분리 레벨(READ COMMITED)이 읽기 시간에 테이블을 잠그지 않으므로 SELECT와 UPDATE 사이에 다른 사용자가 계속 삽입할 수 있습니다.READ COMMITED 분리 수준의 트랜잭션은 SELECT를 잠그지 않습니다.반복 가능 읽기를 사용하는 트랜잭션은 레코드를 잠그지만(찾은 경우) 공백은 잠기지 않습니다.
IF EXISTS (SELECT 1 FROM Table WHERE FieldValue='')
BEGIN
SELECT TableID FROM Table WHERE FieldValue=''
END
ELSE
BEGIN
INSERT INTO TABLE(FieldValue) VALUES('')
SELECT SCOPE_IDENTITY() AS TableID
END
IF ELSE에 대한 자세한 내용은 여기를 참조하십시오.
참고: SQL Server 설치 없이 작성되어 이중으로 확인할 수 있습니다. 하지만 맞는 것 같습니다.
또한 기존 비트를 SELECT가 아닌 SELECT 1로 변경했습니다*. 기존 비트 내에서 반환되는 것은 상관없기 때문입니다. 무언가가 존재하는 한 SCOPE_IDENITY() 비트도 다음 표를 가정하여 ID만 반환하도록 변경했습니다.ID는 ID 열입니다.
당신은 가까웠습니다.
IF EXISTS (SELECT * FROM Table WHERE FieldValue='')
SELECT TableID FROM Table WHERE FieldValue=''
ELSE
BEGIN
INSERT INTO TABLE (FieldValue) VALUES ('')
SELECT TableID FROM Table WHERE TableID=SCOPE_IDENTITY()
END
당신은 단지 구조를 바꾸기만 하면 됩니다.if...else..endif
다소:
if exists(select * from Table where FieldValue='') then begin
select TableID from Table where FieldValue=''
end else begin
insert into Table (FieldValue) values ('')
select TableID from Table where TableID = scope_identity()
end
다음 작업도 수행할 수 있습니다.
if not exists(select * from Table where FieldValue='') then begin
insert into Table (FieldValue) values ('')
end
select TableID from Table where FieldValue=''
또는:
if exists(select * from Table where FieldValue='') then begin
select TableID from Table where FieldValue=''
end else begin
insert into Table (FieldValue) values ('')
select scope_identity() as TableID
end
당신의 테이블에 열쇠가 없는 것처럼 들립니다.당신은 간단히 시도할 수 있어야 합니다.INSERT
만약 그것이 복제된다면, 핵심 제약 조건은 물릴 것이고 그리고.INSERT
실패합니다.걱정할 필요 없습니다. 응용 프로그램이 오류를 인식하거나 무시하지 않도록 해야 합니다.'기본 키'라는 말은 아마도IDENTITY
값. 그것은 모두 매우 좋지만, 당신은 또한 핵심 제약 조건)도 필요합니다.UNIQUE
) 자연 키에 있습니다.
또한 당신의 시술이 너무 많은 것은 아닌지 궁금합니다.각각 '만들기' 및 '읽기' 작업에 대해 별도의 절차를 갖는 것을 고려합니다.
DECLARE @t1 TABLE (
TableID int IDENTITY,
FieldValue varchar(20)
)
--<< No empty string
IF EXISTS (
SELECT *
FROM @t1
WHERE FieldValue = ''
) BEGIN
SELECT TableID
FROM @t1
WHERE FieldValue=''
END
ELSE BEGIN
INSERT INTO @t1 (FieldValue) VALUES ('')
SELECT SCOPE_IDENTITY() AS TableID
END
--<< A record with an empty string already exists
IF EXISTS (
SELECT *
FROM @t1
WHERE FieldValue = ''
) BEGIN
SELECT TableID
FROM @t1
WHERE FieldValue=''
END
ELSE BEGIN
INSERT INTO @t1 (FieldValue) VALUES ('')
SELECT SCOPE_IDENTITY() AS TableID
END
create schema tableName authorization dbo
go
IF OBJECT_ID ('tableName.put_fieldValue', 'P' ) IS NOT NULL
drop proc tableName.put_fieldValue
go
create proc tableName.put_fieldValue(@fieldValue int) as
declare @tableid int = 0
select @tableid = tableid from table where fieldValue=''
if @tableid = 0 begin
insert into table(fieldValue) values('')
select @tableid = scope_identity()
end
return @tableid
go
declare @tablid int = 0
exec @tableid = tableName.put_fieldValue('')
언급URL : https://stackoverflow.com/questions/1488355/if-exists-then-select-else-insert-and-then-select
'programing' 카테고리의 다른 글
목표-c iPhone 백분율로 문자열을 인코딩하시겠습니까? (0) | 2023.09.05 |
---|---|
오라클 11g 또는 12c에서 테이블/열/인덱스 이름 크기 변경 (0) | 2023.09.05 |
노드 스크립트를 실행할 때 현재 셸 컨텍스트에서 작업 디렉터리 변경 (0) | 2023.08.31 |
Selenium WebDriver - 요소를 클릭할 수 있는지 여부를 확인합니다(즉, Dojo 모달 라이트 박스에 의해 가려지지 않음). (0) | 2023.08.31 |
*ngFor에서 동적 ID를 설정하는 방법은 무엇입니까? (0) | 2023.08.31 |