2013-10-10 70 views
12

我正在寫一個基本SELECT查詢,像:檢查SELECT返回任何行存儲過程

SELECT id, pname, pnumber 
FROM tableName 
WHERE pnumber IS NOT NULL 

我想然後通過使用SELECT像這樣的結果執行INSERT

IF {**the above SELECT query returned 0 rows**} 
BEGIN 
    INSERT INTO tableName (pname,pnumber) VALUES ('bob', '38499483') 
END 

我的問題是,我該如何檢查**the above SELECT query returned 0 rows**

+0

此檢查的目的是什麼?如果您正在檢查唯一性,列上的唯一索引更簡單 – podiluska

回答

23
IF NOT EXISTS (SELECT ...) 
BEGIN 
    INSERT ... 
END 

你也可以做到這一點,如果你希望該查詢可能會經常回行(尤其是很多行),它可以提供更好的機會,短路:

IF EXISTS (SELECT ...) 
BEGIN 
    PRINT 'Do nothing.'; 
END 
ELSE 
BEGIN 
    INSERT ... 
END 

..自從IF EXISTS到達匹配的第一行後,它將立即返回。

我不建議僅使用@@ROWCOUNT,因爲您必須每次都實現(並忽略)整個結果集。

+0

當然,我應該知道這個......謝謝。 – muttley91

+0

我喜歡這樣。通常低科技解決方案很好,因爲它們不是針對特定環境的。 SQL代碼通常從SQL Server移植到MySQL到Oracle等... –

1

可以使用@@ROWCOUNT

SELECT id, pname, pnumber 
FROM tableName 
WHERE pnumber IS NOT NULL 

在此之後選擇要求@@ROWCOUNT

IF @@ROWCOUNT = 0 
BEGIN 
    INSERT ... 
END 

這樣就可以返回一些數據,並檢查是否是有結果或不

0

我有看到的人有這個邏輯的設計模式問題。

1 - 測試是否存在記錄。
2 - 如果不存在,請插入記錄。

特別是如果併發發揮作用。根據隔離級別,您可能會有重複的數據或關鍵違規。

爲什麼不把主鍵放在pname和pnumber上。我假設你正在談論一個人桌。

我的例子。

-- 
-- Setup sample table w/data 
-- 

-- Sample table 
create table #person 
( 
    person_id int identity (1, 1), 
    person_name varchar(64) not null, 
    person_no varchar(16) not null 
); 
go 

-- primary key 
alter table #person 
    add primary key (person_no, person_name) 
go 

-- first insert works 
insert into #person (person_name, person_no) values ('bilbo', 123) 
go 

解決方案的關鍵是捕獲主鍵違規。根據您的業務邏輯,忽略此錯誤可能是好的還是壞的。

我決定忽略這個問題。

-- 
-- Ignore primary key violations 
-- 

-- Try these steps 
BEGIN TRY 

    -- Second insert fails 
    insert into #person (person_name, person_no) values ('bilbo', 123) 

END TRY 

-- Error Handler 
BEGIN CATCH 

    -- Ignore PK error 
    IF ERROR_NUMBER() <> 2627 
    SELECT 
     ERROR_NUMBER() AS ErrorNumber 
     ,ERROR_SEVERITY() AS ErrorSeverity 
     ,ERROR_STATE() AS ErrorState 
     ,ERROR_PROCEDURE() AS ErrorProcedure 
     ,ERROR_LINE() AS ErrorLine 
     ,ERROR_MESSAGE() AS ErrorMessage; 
END CATCH 

該解決方案消除重複條目,不報告PK違規。

+0

我試圖只執行INSERT,如果它不存在,因爲我遇到了ASP.NET中的回發問題。所以現有的記錄意味着它不需要被插入,因爲它已經被記錄。據說,我將在即將到來的設計變更中考慮您的答案。謝謝。 – muttley91

+0

我在我的一臺服務器上安裝了Microsoft產品,這些服務器都採用相同的邏輯。如果存在,則返回鍵,否則插入更新鎖。我在我的SQL Sentry Monitoring系統中不斷髮生死鎖通知。我提出的解決方案是上述,但他們還沒有實現它! –

5

在MySQL中檢查no。最後選擇查詢返回的行數

select FOUND_ROWS();