當前位置:首頁 » 存儲配置 » 存儲過程break

存儲過程break

發布時間: 2023-01-07 19:29:49

1. 存儲過程與pl/sql塊有什麼區別

pl/sql塊是沒有存儲過程名字的,寫好後不能被其他模塊調用,而存儲過程可以用call 存儲過程名 這種格式來進行調用,而且存儲過程還能被其他的存儲過程所調用,

2. sql 存儲過程 傳入兩組數組參數

declare@nnvarchar(500)
declare@mnvarchar(500)
set@n='1,2,3,4,5'
set@m='a,b,c,d,e'

createtable#tb(nVARCHAR(500),mVARCHAR(500))
while(1=1)
begin
if(Charindex(',',@n)=0andCharindex(',',@m)=0)
begin
insertinto#tbvalues(@n,@m)
break
end
insertinto#tbvalues(Substring(@n,1,Charindex(',',@n)-1),Substring(@m,1,Charindex(',',@m)-1))
set@n=Right(@n,Len(@n)-Charindex(',',@n))
set@m=Right(@m,Len(@m)-Charindex(',',@m))
end

select*from#tb

droptable#tb

ps:要做好校驗!

3. 存儲過程的測試一直在執行,關不掉

1、存儲過程中是否有 LOOP ?
如果有 的在end loop 添加 EXIT WHEN 游標名%NOTFOUND (意思是如果沒有這個游標,就跳出)
2、沒有loop 的話
手動停止掉當前的存儲過程吧。語句如下:
--先查運行的存儲過程sid
select /*rule*/ sid from v$access where object='存儲過程名'
--通過sid 找到serial
select sid ,serial#,paddr from v$session where sid='上一句查到的sid'
--kill 掉存儲過程
alter system kill session 'sid','serial#'

4. mssql 存儲過程中循環如何寫,在循環中用什麼語句跳出循環呢,在線等

給你個例子:

for loop是這樣的:
createprocere pro
begin
declare aintdefault1;
label1: loop
if a<6then
selecta;
seta=a+1;
iterate label1;
endif;
leave label1;跳出循環
endloop label1;
end

while是這樣的:
createprocere pro
begin
declare aintdefault4;
while a<10 do
selecta;
seta=a+1;
endwhile;
end

5. mysql存儲過程報錯 找的快哭了...

加一個事務
多加幾個判斷就可以處理存儲過程中的異常了,請採納!

6. 如何給存儲過程,傳一個數組參數

方法一 分割

例:通過SQL Server存儲過程傳送數組參數刪除多條記錄

eg. ID 值為'1,2,3' 以下存儲過程就是刪除表中id號為1,2,3的記錄:

CREATE PROCEDURE DeleteNews
@ID nvarchar(500)
as
DECLARE @PointerPrev int
DECLARE @PointerCurr int
DECLARE @TId int
Set @PointerPrev=1

while (@PointerPrev < LEN(@ID))
Begin
Set @PointerCurr=CharIndex(',',@ID,@PointerPrev)
if(@PointerCurr>0)
Begin
set @TId=cast(SUBSTRING(@ID,@PointerPrev,@PointerCurr-@PointerPrev) as int)
Delete from News whereID=@TID
SET @PointerPrev = @PointerCurr+1
End
else
Break
End
--刪除最後一個,因為最後一個後面沒有逗號,所以在循環中跳出,需另外再刪除
set @TId=cast(SUBSTRING(@ID,@PointerPrev,LEN(@ID)-@PointerPrev+1) as int)
Delete from News whereID=@TID
GO

這個方法麻煩不?於是又有另外一種方法——臨時表

方法二 Table對象

傳3個參數,都是數組形式還有時間類型用存儲過程更新

@Oid = 1,2,3,4

@Did = 111,222,333,444

@DateArr = '2007-1-1,2007-1-2,2007-1-3,2007-1-4'

CREATE proc Test999

@Oid nvarchar(1000)--ID1

,@Did nvarchar(1000)--ID2

,@DateArr nvarchar(1000)--日期

AS

DECLARE @id1s varchar(8000), @id2s varchar(8000), @dates varchar(8000)

set @id1s=@Oid

set @id2s=@Did

set @dates = @DateArr

-- 調用函數實現處理

SELECT @id1s=@id1s, @id2s=@id2s,@dates = @dates

UPDATE A SET terminate_time = B.dt

FROM [Table] A,(

SELECT

id1 = CONVERT(int, Desk_id.value),

id2 = CONVERT(int, room_id.value),

dt = CONVERT(datetime, terminate_time.value)

FROM dbo.f_splitstr(@id1s) Desk_id, dbo.f_splitstr(@id2s) room_id, dbo.f_splitstr(@dates) terminate_time

WHERE Desk_id.id = room_id.id

AND Desk_id.id = terminate_time.id

) B

WHERE A.Desk_id = B.ID1 AND A.room_id = B.ID2

GO這個還用到一個函數f_splitstr

CREATE FUNCTION dbo.f_splitstr(

@str varchar(8000)

)RETURNS @r TABLE(id int IDENTITY(1, 1), value varchar(5000))

AS

BEGIN

DECLARE @pos int

SET @pos = CHARINDEX(',', @str)

WHILE @pos > 0

BEGIN

INSERT @r(value) VALUES(LEFT(@str, @pos - 1))

SELECT

@str = STUFF(@str, 1, @pos, ''),

@pos = CHARINDEX(',', @str)

IF @str > ''

INSERT @r(value) VALUES(@str)

RETURN

這個方法更加可怕~~~輾轉網路,找到了一個還不錯的方法,用OPENXML,這個SQL2000就支持了。

方法三 xml

應該用SQL2000 OpenXML更簡單,效率更高,代碼更可讀:

CREATE Procere [dbo].[ProctListUpdateSpecialList]
(
@ProctId_Array NVARCHAR(2000),
@MoleId INT
)

AS

delete from ProctListSpecial whereMoleId=@MoleId

-- If empty, return
IF (@ProctId_Array IS NULL OR LEN(LTRIM(RTRIM(@ProctId_Array))) = 0)
RETURN

DECLARE @idoc int

EXEC sp_xml_preparedocument @idoc OUTPUT, @ProctId_Array

Insert into ProctListSpecial (MoleId,ProctId)
Select
@MoleId,C.[ProctId]
FROM
OPENXML(@idoc, '/Procts/Proct', 3)
with (ProctId int ) as C
where
C.[ProctId] is not null

EXEC sp_xml_removedocument @idoc

哇,看起來還是很復雜的說。有木有更好的辦法呢?

既然是OPENXML,為啥不用XML呢?於是查到,SQL2005以上都支持XML。Good,找到一片天了。

利用SQL2005的XML/XQuery功能,可以很方便的解決傳數組參數的問題。

declare @xml xml
set @xml = '<?xml version="1.0"?>
<ArrayOfInt>
<int>1</int>
<int>2</int>
<int>3</int>
</ArrayOfInt>'

select N.value( '(text())[1]','int' ) RoomId from @xml.nodes('/ArrayOfInt/int') V(N)

結果就是

註:上面的數據類型為XML

這樣就可以給存儲過程傳一個集合了,一般是數組,比如主鍵的集合。然後可用通過主鍵集合來查詢記錄。

客戶端可用使用序列化,把list轉化成xml。不過在序列化過程中,遇到了一些小麻煩。

1. .net默認是utf-16,SQL只認識utf-8

2. 出現很討厭的xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"

可以用我這個類

public static class SerializeHelper
{
private static readonly XmlSerializerNamespaces Namespaces = new XmlSerializerNamespaces();

static SerializeHelper()
{
//去掉 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
Namespaces.Add(string.Empty, string.Empty);
}

public static string SerializeXml<T>(T obj)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (MemoryStream stream = new MemoryStream())
{
serializer.Serialize(stream, obj, Namespaces);
return Encoding.UTF8.GetString(stream.ToArray());
}
}

public static T DeserializeXml<T>(string obj)
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
using (StringReader reader = new StringReader(obj))
{
return (T)serializer.Deserialize(reader);
}
}
}

SQL與XML,XQuery結合起來,功能會很強大的。

7. sql server 存儲過程如何對select語句的結果集進行循環操作

DECLARE
@id INT, @value VARCHAR(10);
BEGIN
-- 定義游標.
DECLARE c_test_main CURSOR FAST_FORWARD FOR
SELECT id,valueFROM test_main;
-- 打開游標.
OPEN c_test_main;

WHILE 1=1
BEGIN
-- 填充數據.
FETCH NEXT FROM c_test_main INTO @id, @value;
-- 假如未檢索到數據,退出循環.
IF@@fetch_status!= 0 BREAK;

PRINT @value;
END;

-- 關閉游標
CLOSE c_test_main;
-- 釋放游標.
DEALLOCATE c_test_main;
END;go

8. mysql存儲過程 in 怎麼用

out 表示輸出的參數,存儲過程調用 代碼 需要獲得此參數值。
in 表示輸入參數,默認為in

例1、一個簡單存儲過程游標實例

復制代碼代碼如下:

DELIMITER $$
DROP PROCEDURE IF EXISTS getUserInfo $$
CREATE PROCEDURE getUserInfo(in date_day datetime)
--
-- 實例
-- 存儲過程名為:getUserInfo
-- 參數為:date_day日期格式:2008-03-08
--
BEGIN
declare _userName varchar(12); -- 用戶名
declare _chinese int ; -- 語文
declare _math int ; -- 數學
declare done int;
-- 定義游標
DECLARE rs_cursor CURSOR FOR SELECT username,chinese,math from userInfo where datediff(createDate, date_day)=0;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
-- 獲取昨天的日期
if date_day is null then
set date_day = date_add(now(),interval -1 day);
end if;
open rs_cursor;
cursor_loop:loop
FETCH rs_cursor into _userName, _chinese, _math; -- 取數據

if done=1 then
leave cursor_loop;
end if;
-- 更新表
update infoSum set total=_chinese+_math where UserName=_userName;
end loop cursor_loop;
close rs_cursor;

END$$
DELIMITER ;

例2、存儲過程游標循環跳出現
在MySQL的存儲過程中,游標操作時,需要執行一個conitnue的操作.眾所周知,MySQL中的游標循環操作常用的有三種,LOOP,REPEAT,WHILE.三種循環,方式大同小異.以前從沒用過,所以記下來,方便以後查閱.
1.REPEAT

復制代碼代碼如下:

REPEAT
Statements;
UNTIL expression
END REPEAT
demo
DECLARE num INT;
DECLARE my_string VARCHAR(255);
REPEAT
SET my_string =CONCAT(my_string,num,',');
SET num = num +1;
UNTIL num <5
END REPEAT;

2.WHILE

復制代碼代碼如下:

WHILE expression DO
Statements;
END WHILE
demo
DECLARE num INT;
DECLARE my_string VARCHAR(255);
SET num =1;
SET str ='';
WHILE num < span>10DO
SET my_string =CONCAT(my_string,num,',');
SET num = num +1;
END WHILE;
3.LOOP(這裡面有非常重要的ITERATE,LEAVE)
代碼如下 復制代碼
DECLARE num INT;
DECLARE str VARCHAR(255);
SET num =1;
SET my_string ='';
loop_label: LOOP
IF num <10THEN
LEAVE loop_label;
ENDIF;
SET num = num +1;
IF(num mod3)THEN
ITERATE loop_label;
ELSE
SET my_string =CONCAT(my_string,num,',');
ENDIF;
END LOOP;

PS:可以這樣理解ITERATE就是我們程序中常用的contiune,而ITERATE就是break.當然在MySQL存儲過程,需要循環結構有個名稱,其他都是一樣的.
例3,mysql 存儲過程中使用多游標

先創建一張表,插入一些測試數據:

復制代碼代碼如下:

DROP TABLE IF EXISTS netingcn_proc_test;
CREATE TABLE `netingcn_proc_test` (
`id` INTEGER(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20),
`password` VARCHAR(20),
PRIMARY KEY (`id`)
)ENGINE=InnoDB;
insert into netingcn_proc_test(name, password) values
('procere1', 'pass1'),
('procere2', 'pass2'),
('procere3', 'pass3'),
('procere4', 'pass4');下面就是一個簡單存儲過程的例子:
drop procere IF EXISTS test_proc;
delimiter //
create procere test_proc()
begin
-- 聲明一個標志done, 用來判斷游標是否遍歷完成
DECLARE done INT DEFAULT 0;
-- 聲明一個變數,用來存放從游標中提取的數據
-- 特別注意這里的名字不能與由游標中使用的列明相同,否則得到的數據都是NULL
DECLARE tname varchar(50) DEFAULT NULL;
DECLARE tpass varchar(50) DEFAULT NULL;
-- 聲明游標對應的 SQL 語句
DECLARE cur CURSOR FOR
select name, password from netingcn_proc_test;
-- 在游標循環到最後會將 done 設置為 1
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
-- 執行查詢
open cur;
-- 遍歷游標每一行
REPEAT
-- 把一行的信息存放在對應的變數中
FETCH cur INTO tname, tpass;
if not done then
-- 這里就可以使用 tname, tpass 對應的信息了
select tname, tpass;
end if;
UNTIL done END REPEAT;
CLOSE cur;
end
//
delimiter ;
-- 執行存儲過程
call test_proc();

需要注意的是變數的聲明、游標的聲明和HANDLER聲明的順序不能搞錯,必須是先聲明變數,再申明游標,最後聲明HANDLER。上述存儲過程的例子中只使用了一個游標,那麼如果要使用兩個或者更多游標怎麼辦,其實很簡單,可以這么說,一個怎麼用兩個就是怎麼用的。例子如下:

復制代碼代碼如下:

drop procere IF EXISTS test_proc_1;
delimiter //
create procere test_proc_1()
begin
DECLARE done INT DEFAULT 0;
DECLARE tid int(11) DEFAULT 0;
DECLARE tname varchar(50) DEFAULT NULL;
DECLARE tpass varchar(50) DEFAULT NULL;
DECLARE cur_1 CURSOR FOR
select name, password from netingcn_proc_test;
DECLARE cur_2 CURSOR FOR
select id, name from netingcn_proc_test;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
open cur_1;
REPEAT
FETCH cur_1 INTO tname, tpass;
if not done then
select tname, tpass;
end if;
UNTIL done END REPEAT;
CLOSE cur_1;
-- 注意這里,一定要重置done的值為 0
set done = 0;
open cur_2;
REPEAT
FETCH cur_2 INTO tid, tname;
if not done then
select tid, tname;
end if;
UNTIL done END REPEAT;
CLOSE cur_2;
end
//
delimiter ;
call test_proc_1();

上述代碼和第一個例子中基本一樣,就是多了一個游標聲明和遍歷游標。這里需要注意的是,在遍歷第二個游標前使用了set done = 0,因為當第一個游標遍歷玩後其值被handler設置為1了,如果不用set把它設置為 0 ,那麼第二個游標就不會遍歷了。當然好習慣是在每個打開游標的操作前都用該語句,確保游標能真正遍歷。當然還可以使用begin語句塊嵌套的方式來處理多個游標,例如:

復制代碼代碼如下:

drop procere IF EXISTS test_proc_2;
delimiter //
create procere test_proc_2()
begin
DECLARE done INT DEFAULT 0;
DECLARE tname varchar(50) DEFAULT NULL;
DECLARE tpass varchar(50) DEFAULT NULL;
DECLARE cur_1 CURSOR FOR
select name, password from netingcn_proc_test;
DECLARE cur_2 CURSOR FOR
select id, name from netingcn_proc_test;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
open cur_1;
REPEAT
FETCH cur_1 INTO tname, tpass;
if not done then
select tname, tpass;
end if;
UNTIL done END REPEAT;
CLOSE cur_1;
begin
DECLARE done INT DEFAULT 0;
DECLARE tid int(11) DEFAULT 0;
DECLARE tname varchar(50) DEFAULT NULL;
DECLARE cur_2 CURSOR FOR
select id, name from netingcn_proc_test;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
open cur_2;
REPEAT
FETCH cur_2 INTO tid, tname;
if not done then
select tid, tname;
end if;
UNTIL done END REPEAT;
CLOSE cur_2;
end;
end
//
delimiter ;
call test_proc_2();

熱點內容
android打飛機 發布:2025-07-04 23:59:34 瀏覽:209
mr底層演算法 發布:2025-07-04 23:14:59 瀏覽:781
怎麼注冊作業盒子密碼 發布:2025-07-04 23:14:51 瀏覽:923
速達伺服器ip 發布:2025-07-04 23:07:38 瀏覽:262
哪裡能下載安卓版刺激戰場 發布:2025-07-04 23:02:27 瀏覽:520
android微信推送消息推送消息 發布:2025-07-04 22:56:52 瀏覽:386
android分享文件 發布:2025-07-04 22:56:40 瀏覽:404
c語言方程的根 發布:2025-07-04 22:55:33 瀏覽:449
什麼電腦單機游戲好玩又免費配置低 發布:2025-07-04 22:51:27 瀏覽:421
真香配置有哪些 發布:2025-07-04 22:49:05 瀏覽:208