1. SQL ストアド プロシージャの概要
大規模なデータベース システムでは、ストアド プロシージャとトリガーが非常に重要な役割を果たします。ストアド プロシージャであってもトリガーであっても、SQL ステートメントとフロー制御ステートメントの集合です。本質的に、トリガーはストアド プロシージャでもあります。ストアド プロシージャは操作中に実行モードを生成するため、後で再度実行するときに非常に高速に実行されます。 SQL Server 2000 は、ユーザー定義ストアド プロシージャの機能を提供するだけでなく、ツールとして使用できるシステム ストアド プロシージャも多数提供します
1.1 概念
ストアド プロシージャ (Stored Procedure) は、特定のストアド プロシージャを完了するための SQL のセットです関数 ステートメント セットがコンパイルされ、データベースに保存されます。ユーザーは、ストアド プロシージャの名前を指定し、パラメーターを指定することによって (ストアド プロシージャにパラメーターがある場合)、ストアド プロシージャを実行します。
SQL Server のシリーズ バージョンでは、ストアド プロシージャは、システム提供のストアド プロシージャとユーザー定義のストアド プロシージャの 2 つのカテゴリに分類されます。システム プロシージャは主にマスター データベースに格納され、sp_ というプレフィックスが付けられます。システム ストアド プロシージャは主にシステム テーブルから情報を取得するため、システム管理者が SQL Server を管理できるようになります。システム ストアド プロシージャを通じて、MS SQL Server の多くの管理アクティビティや情報アクティビティ (データベース オブジェクトやデータベース情報の理解など) をスムーズかつ効果的に完了できます。これらのシステム ストアド プロシージャは master データベースに配置されますが、データベース名の先頭にストアド プロシージャ名を付けなくても、他のデータベースで呼び出すことができます。新しいデータベースが作成されると、いくつかのシステム ストアド プロシージャが新しいデータベースに自動的に作成されます。ユーザー定義ストアド プロシージャは、ユーザーによって作成され、特定の機能 (ユーザーが必要とするデータ情報のクエリなど) を実行できるストアド プロシージャです。この章で説明するストアド プロシージャは、主にユーザー定義のストアド プロシージャを指します。
1.2 ストアド プロシージャの利点
Transaction-SQL は、MS SQL Server を使用してアプリケーションを作成する場合の主要なプログラミング言語です。 Transaction-SQL をプログラミングに使用する場合、2 つの方法があります。 1 つは、Transaction-SQL プログラムをローカルに保存し、コマンドを SQL Server に送信して結果を処理するアプリケーションを作成することです。 2 つ目は、Transaction-SQL で作成された一部のプログラムをストアド プロシージャとして SQL Server に保存し、ストアド プロシージャを呼び出してデータ結果を処理するアプリケーションを作成できることです。ストアド プロシージャはパラメータを受け取ることで呼び出し元に結果セットを返すことができます。結果セットの形式は呼び出し元によって決定され、呼び出しが成功したか失敗したかを示すステータス値が返され、ストアド プロシージャ内の別のストアド プロシージャを呼び出すことができます。
通常、クライアント コンピューター上で Transaction-SQL で作成されたプログラムを呼び出すのではなく、SQL Server でストアド プロシージャを使用する 2 番目の方法を使用することを好みます。その理由は、ストアド プロシージャには次の利点があるためです。プロシージャにより、標準コンポーネント プログラミングが可能になります
ストアド プロシージャを作成した後は、ストアド プロシージャの SQL ステートメントを書き直すことなく、プログラム内で複数回呼び出すことができます。さらに、データベースの専門家はいつでもストアド プロシージャを変更できますが、アプリケーションのソース コードには影響を与えません (アプリケーションのソース コードにはストアド プロシージャの呼び出しステートメントのみが含まれるため)。したがって、プログラムの移植性が大幅に向上します。
(2) ストアド プロシージャはより高速な実行速度を実現できます
操作に大量の Transaction-SQL コードが含まれている場合、または複数回実行される場合、ストアド プロシージャはバッチ処理よりもはるかに高速に実行されます。ストアド プロシージャはプリコンパイルされているため、ストアド プロシージャが初めて実行されるときに、クエリ オプティマイザーがそれを分析して最適化し、最終的にシステム テーブルに保存される実行プランを提供します。バッチ Transaction-SQL ステートメントは、実行するたびにコンパイルおよび最適化する必要があるため、速度は比較的遅くなります。
(3) ストアド プロシージャはネットワーク トラフィックを削減できます
データベース オブジェクトに対する同じ操作 (クエリ、変更など) の場合、この操作に含まれる Transaction-SQL ステートメントがストアド プロシージャに編成されている場合、ストアド プロシージャがクライアント コンピュータで呼び出されると、呼び出しステートメントのみがネットワーク経由で送信されます。それ以外の場合は複数の SQL ステートメントになるため、ネットワーク トラフィックが大幅に増加し、ネットワーク負荷が軽減されます。
(4) ストアドプロシージャをセキュリティ機構として最大限に活用できます
システム管理者は、特定のストアドプロシージャの実行権限を制限することで、対応するデータアクセス権限を制限し、不正なユーザーによるデータへのアクセスを回避し、データのセキュリティを確保することができます。 (ストアド プロシージャのこのアプリケーションについては、第 14 章「SQL Server のユーザーとセキュリティの管理」でより明確に紹介します)
注: ストアド プロシージャにはパラメータと戻り値の両方がありますが、関数とは異なります。ストアド プロシージャの戻り値は、実行が成功したかどうかを示すだけであり、関数のように直接呼び出すことはできません。つまり、ストアド プロシージャを呼び出すときは、ストアド プロシージャ名の前に EXEC 予約語が必要です。
プロシージャの作成 sp_name //sp_name ストアド プロシージャに付ける名前
Begin
……
End
Proc dboの作成
ストアド プロシージャのパラメータ
AS
実行ステートメント
RETURN
ストアド プロシージャ
GO
例:
-- ストアド プロシージャが作成されるデータベース
Use Test
-- 作成されるストアド プロシージャ名が存在するかどうかを確認します
if Exists(Select name From) sysobjects Where name='csp_AddInfo' And
type='P')
-- ストアド プロシージャを削除
Drop Procedure dbo.csp_AddInfo
Go
-- ストアド プロシージャを作成
作成するProc dbo .csp_AddInfo
- - ストアド プロシージャ パラメーター
@UserName varchar(16),
@Pwd varchar(50),
@Age smallint,
@*** varchar(6)
AS
-- ストアド プロシージャ ステートメントの本文
Uname (UserName,Pwd,Age,***) に挿入
values (@UserName,@Pwd,@Age,@***)
RETURN
-- 実行
GO
-- ストアド プロシージャを実行します
EXEC csp_AddInfo 'Junn.A','123456',20,' Male'
新しいストアド プロシージャの名前。プロシージャ名は識別子の規則に準拠する必要があり、データベースとその所有者に対して一意である必要があります。
ローカル一時プロシージャを作成するには、procedure_name の前に数字文字 (#procedure_name) を追加します。グローバル一時プロシージャを作成するには、procedure_name の前に 2 つの数字文字 (##procedure_name) を追加します。完全な名前 (# または ## を含む) は 128 文字を超えることはできません。プロセス所有者の名前の指定はオプションです。
2.2 ストアド プロシージャを呼び出す
Call プロシージャ sp-name ()
注: ストアド プロシージャにパラメータが渡されていない場合でも、ストアド プロシージャ名の後にかっこを追加する必要があります
1) 最初の方法: を使用します出力パラメータ
USE AdventureWorks;
GO
IF OBJECT_ID ( 'Production.usp_GetList', 'P' ) IS NOT NULL
DROP PROCEDURE Production.usp_GetList;
GO
手順を作成するProduction.usp_GetList
@product varchar(40)
、@maxpricemoney
、@comparepricemoney OUTPUT
、@listpricemoney OUT
AS
SELECT p.name AS Product、p.ListPrice AS '定価'
FROM Production.Product p
JOIN Production.ProductSubcategory s
ON p.ProductSubcategoryID = s.ProductSubcategoryID
WHERE s.name LIKE @product AND p.ListPrice < @maxprice;
-- 出力を設定します変数 @ listprice.
SET @listprice = (SELECT MAX(p.ListPrice)
FROM Production.Product p
JOIN Production.ProductSubcategory s
ON p.ProductSubcategoryID = s.ProductSubcategoryID
WHERE s.name LIKE @product AND p.ListPrice < @maxprice);
-- 出力変数 @compareprice.
SET @compareprice = @maxprice;
GO
-- 別のストアド プロシージャが呼び出し先:
Create Proc Test
as
DECLARE @comparepricemoney, @costmoney
EXECUTE Production.usp_GetList '%Bikes%', 700,
@compareprice OUT,
@cost OUTPUT
IF @cost < = @compareprice
BEGIN
PRINT 'これらの商品は
$ 未満で購入できます'+RTRIM(CAST(@compareprice AS varchar(20)))+'.'
END
ELSE
PRINT ' このカテゴリのすべての製品の価格は次を超えています
$'+ RTRIM(CAST(@compareprice AS varchar(20)))+'.'
2) 2 番目の方法: 一時テーブルを作成します
プロシージャ GetUserName
を
として作成します
begin
select 'UserName'
テーブル#tempTable (userName nvarchar(50))を作成
#tempTable(userName)に挿入
--使い切るその後、一時テーブルをクリアする必要があります
procedure a
begin
...
insert #table exec b
end
procedure b
begin
...
insert #table exec c
select * from #table
end
procedure c
begin
...
select * from sometable
--ここでは、a が b の結果セットを調整し、b が c の結果セットを調整するようなアプリケーションも b にあります。これは許可されていません、
3) 3 番目の方法: 変数を宣言し、exec(@sql) で実行します:
2.3 ストアド プロシージャを削除、
drop プロシージャ sp_name//
注: 1 つのストアド プロシージャ内で別のストアド プロシージャを削除することはできません。プロシージャ、別のストアド プロシージャのみを呼び出すことができます
2.4 ストアド プロシージャ情報を表示します
1.プロシージャのステータスを表示
データベース内のすべてのストアド プロシージャの基本情報(属しているデータベース、ストアド プロシージャの名前など)を表示します、作成時間など
2. 作成プロシージャ sp_name を表示
2.5 コメント
二重水平バー: --
c スタイル: /* コメントの内容 */ 通常、複数行のコメントに使用されます
2.6 ループ文2.6.1 If
IF条件
BEGIN
END
ELSE
BEGIN
実行ステートメント
END
IF @d = 1
BEGIN
--Print
PRINT '正しい'
END
ELSE BEGIN
END
2.6.2 複数条件選択文
Sql 複数条件選択文.
DECLARE @iRet INT, @PKDisp VARCHAR(20)
SET @iRet = 1
Select @iRet =
CASE
WHEN @PKDisp = '1' THEN 1
WHEN @PKDisp = 'Two' THEN 2
WHEN @PKDisp = 'three' THEN 3
WHEN @PKDisp = 'four' THEN 4
WHEN @PKDisp = '5' THEN 5
ELSE 100
END
2.6.3 ループ文
WHILE条件BEGIN
実行文
END
例: CREATE PROCEDURE [dbo].[P_TestWh] [ilr]
as
宣言@ i INT
SET @i = 1
WHILE @i< ;1000000 BEGIN
set @i=@i+1
END
PRINT @i
exec [dbo]。 [p_testhills 3.1 custom変数:int a = 100を置き換えることができます。はユーザー変数とシステム変数に分けられ、システム変数はセッション変数とグローバルレベル変数に分けられます
ユーザー変数: ユーザー変数名は通常 @ で始まります。ユーザー変数を乱用すると、プログラムの理解と管理が困難になります
-- SQL で変数を宣言する場合は、変数の前に @ 記号を追加する必要があります
DECLARE @I INT
SET @I = 30
--複数の変数の宣言
DECLARE @s varchar(10),@a INT
3.2 演算子3.2 .1 算術演算子
+ SET var1=2+2 の加算4
- SET var2= の減算3-2; 1
* 乗算 SET var3=3*2; 6
/ 除算 SET var5=10 DIV 3; 3
% モジュロ SET var6=10%3;
> 1>2 False
>= 以上to 3>=2 True
BETWEEN 2 つの値の間 5 BETWEEN 1 AND 10 True
NOT BETWEEN 2 つの値の間ではない 5 NOT BETWEEN 1 AND 10 False
NOT IN はセットにありません 5 NOT IN (1,2,3,4) True
= は 2=3 に等しい False<>、!= 2<>3 に等しくない False
<=> 2 つの NULL 値が等しいかどうかを厳密に比較します NULL<=>NULL TrueLIKE 単純なパターン マッチング "Guy Harrison" LIKE "Guy%" True
REGEXP 正規表現 "Guy Harrison" と一致する REGEXP "[ Gg]reg" False
IS NULL は空です 0 IS NULL False
IS NOT NULL は空ではありません 0 IS NOT NULL True
3. 論理演算子
4. ビット演算子
| または
& および
<< leftシフト
>> 右シフト
~ not (単項演算、ビットごとの否定)
プロシージャの作成 | 関数 ([[IN |OUT |INOUT ] パラメータ名 データ型...])
IN 入力パラメータ
を表します。ストアド プロシージャを呼び出すときに、このパラメータの値を指定する必要があります。ストアド プロシージャ中にこのパラメータの値が変更された場合、それを返すことはできません。これはデフォルト値です。
OUT 出力パラメータ
呼び出し時に指定され、変更および返すことができます
--最大値を見つけるストアド プロシージャを作成します
@a int, -- input
@b int, -- 入力
@Returnc int 出力 --出力
AS
if (@a>@b)set @Returnc =@aelseset @Returnc =@b-- Call
declare @Returnc int
exec P_Max 2,3、@Returnc Output
select @Returnc
5. 関数ライブラリ
MySQL ストアド プロシージャの基本関数には、文字列型、数値が含まれます。 type, date type
5.1 String class
CHARSET(str) //文字列の文字セットを返す
CONCAT (string2 [,…]) //文字列を接続する
INSTR (string, substring) //文字列内で部分文字列が最初に出現する位置。存在しない場合は 0 を返します
LCASE (string2) //小文字に変換します
LEFT (string2, length) //string2 の左から長さの文字を取得します
LENGTH (string) //文字列の長さ
LOAD_FILE (file_name) //ファイルから内容を読み取ります
LOCATE (substring, string [,start_position]) INSTRと同じですが、開始位置を指定できます
LPAD (string2, length, Pad) //パッドを繰り返し追加しますto string 先頭から文字列長が length になるまで
LTRIM (string2) //先頭のスペースを削除
REPEAT (string2,count) //count 回繰り返します
REPLACE (str,search_str,replace_str) //search_str を replace_str に置き換えますstr
RPAD (string2, length,pad) //長さが length になるまで str の後にパッドを追加します
RTRIM (string2) //バックエンドのスペースを削除します
STRCMP (string1, string2) //2 つの文字列のサイズを比較しますbycharacter,
SUBSTRING (str,position [,length]) //str の位置から開始し、length 文字を取ります,
注: MySQL で文字列を処理する場合、デフォルトの最初の文字の添え字は 1、つまりパラメータの位置です1 以上である必要があります
mysql> select substring('abcd',0,2);
+————————–+
| ———————–+
|
+————————–+
セット内の 1 行 (0.00 秒)
+————————–+
| 部分文字列('abcd',1,2) |
+————————–+
|
+——————— —–+
セット内の 1 行 (0.02 秒)
UCASE (string2) //に変換しますuppercase
RIGHT(string2,length) //string2 の最後の長さの文字を取得
SPACE(count) //count 個のスペースを生成
BIN (decmal_number) //変換10進数から2進数へ
CEILING (number2) //切り上げ
CONV(number2, from_base,to_base) //16進数変換
FLOOR (number2) //切り捨て
FORMAT (number,decmal_places) //小数点以下の桁数を保持
HEX (DecimalNumber) //16 進数に変換します
注: HEX( ) は文字列で渡すことができ、その ASC-11 コードが返されます。たとえば、HEX('DEF') は 4142143 を返します
で渡すこともできます。たとえば、HEX(25) は 19 を返します
LEAST (number,number2 [,..]) //最小値を求めます
MOD (numerator,denominator) //余りを求めます。
POWER (number,power) //指数を求めます
RAND([seed]) //乱数
ROUND (number [,decimals ]) //四捨五入、小数点以下の桁数]
mysql> select Round(1.23);
+————-+
|
+————-+
| 1 |
+————-+
1 行 (0.00 秒)
+——-+
| ——-+
| 2 |
+————-+
1 行 (0.00 秒)
( 2) 小数点以下の桁数を設定して浮動小数点データを返すことができます
selectround( 1.567,2);
+——————-+| ラウンド(1.567,2) |
+———— —-+
| 1.57 |
+——————-+
1 行in set (0.00 秒)
SIGN (number2) //戻り符号、正または負、または 0
5.3 日付型
ADDTIME (date2 ,time_interval ) // date2 に time_interval を追加
CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) // タイムゾーンを変換
CURRENT_DATE ( ) // 現在の日付
CURRENT_TIME ( ) // 現在の時刻
CURRENT_TIMESTAMP ( ) // 現在Timestamp
DATE (datetime) // datetime の日付部分を返します
DATE_ADD (date2, INTERVAL d_value d_type) // date2 に日付または時刻を追加します
DATE_FORMAT (datetime,FormatCodes) // formatcodes 形式を使用して datetime を表示します
DATE_SUB ( date2 , INTERVAL d_value d_type) // date2 から時間を減算します
DATEDIFF (date1, date2) // 2 つの日付の差
DAY (date) // date の日を返します
DAYNAME (date) // 英語の曜日
DAYOFWEEK ( date) //平日 (1-7)、1 は日曜日
DAYOFYEAR (date) //年間の日
EXTRACT (interval_name FROM date) //date から日付の指定部分を抽出
MAKEDATE (year , day ) //年と日を指定して、日付文字列を生成します
MAKETIME (時、分、秒) //時間文字列を生成します
MONTHNAME (date) //英語の月名
NOW () //現在時刻
SEC_TO_TIME (秒) //秒を時刻に変換します
STR_TO_DATE (string, format) //文字列を時刻に変換し、形式 format で表示します
TIMEDIFF (datetime1, datetime2) //2 つの時刻の差
TIME_TO_SEC (time) / /Time秒まで]
WEEK (date_time [,start_of_week ]) //週数
YEAR (datetime) //年
DAYOFMONTH(datetime) //月の日
HOUR(datetime) //時間
LAST_DAY (date) // date の月の最後の日付
MICROSECOND(datetime) //マイクロ秒
MONTH(datetime) //Month
MINUTE(datetime) //Minutes
注: INTERVAL で使用可能な型: DAY、DAY_HOUR 、 DAY_MINUTE ,DAY_SECOND ,HOUR ,HOUR_MINUTE ,HOUR_SECOND ,MINUTE ,MINUTE_SECOND,MONTH ,SECOND ,YEAR
DECLARE variable_name [,variable_name...] datatype [DEFAULT value]
このうち、datatype は次のような mysql のデータ型です。 INT、FLOAT、DATE、VARCHAR(長さ)
例:
DECLARE l_int INT unsigned デフォルト 4000000;
DECLARE l_numeric NUMERIC(8,2) DEFAULT 9.95;
DECLARE l_date DATE DEFAULT '1999-12-31';
宣言するl_datetime DATETIME DEFAULT '1999-12-31 23:59:59';
DECLARE l_varchar VARCHAR(255) DEFAULT 'これはパディングされません';
6. ストアド プロシージャの適用
SQL ストアド プロシージャのページング方法:
ストアド プロシージャ:
CREATE プロシージャ p_splitpage
@sql nvarchar(4000), -- 実行される SQL 文
@page int=1, -- 表示されるページ番号
@pageSize int, - -各ページのサイズ
@pageCount int=0 out, --ページの総数
@recordCount int=0 out --レコードの総数
as
set nocount on
declare @p1 int
exec sp_cursoropen @p1 Output ,@sql ,@scrollopt=1,@ccopt=1,@rowcount=@pagecount 出力
set @recordCount = @pageCount
select @pagecount=ceiling(1.0*@pagecount/@pagesize)
,@page=(@page -1) *@pagesize+1
exec sp_cursorfetch @p1,16,@page,@pagesize
exec sp_cursorclose @p1
GO
ASP ページのコンテンツ
sql = "削除された tabNews から id、c_s_name を選択<>1 オーダーID Desc "
page = cint(page_get)
if page_post<>""then
page = cint(page_post)
end if
if not page > 0 then
page = 1
end if
pagesize=20'ページあたりの項目数
set cmd = server.CreateObject("adodb.command")
cmd.ActiveConnection = conn
cmd.CommandType = 4
cmd.CommandText = "p_SplitPage"
cmd.Parameters.Append cmd.CreateParameter(" @sql" ,8,1, 4000, sql)
cmd.Parameters.Append cmd.CreateParameter("@page",4,1, 4, page)
cmd.Parameters.Append cmd.CreateParameter("@pageSize", 4,1 , 4, pageSize)
cmd.Parameters.Append cmd.CreateParameter("@pageCount",4,2, 4, pageCount)
cmd.Parameters.Append cmd.CreateParameter("@recordCount",4,2, 4、recordCount )
set rs = cmd.Execute
set rs = rs.NextRecordSet
pageCount = cmd.Parameters("@pageCount").value
recordCount = cmd.Parameters("@recordCount").value
if pageCount = 0 then pageCount = 1
if page>pageCount then
response.Redirect("?page="&pageCount)
end if
set rs = cmd.Execute
Cursor
1. コンセプト
Cursor (カーソル)これにより、ユーザーは SQL Server によって返された結果セットに行ごとにアクセスできるようになります。
カーソルを使用する主な理由の 1 つは、コレクション操作を単一レコードの処理に変換することです。 SQL 言語を使用してデータベースからデータを取得した後、結果はメモリ領域に配置され、多くの場合、結果は複数のレコードを含むコレクションになります。カーソル メカニズムを使用すると、ユーザーは SQL サーバー内のこれらのレコードに 1 行ずつアクセスし、ユーザー自身の希望に応じてこれらのレコードを表示および処理できます。
2. カーソルの利点
カーソルの定義から、カーソルが実際のアプリケーションで重要な役割を果たせる次のようなカーソルの利点が得られます:
1) プログラムがクエリによって返された行セット内の各行に対して同じまたは異なる操作を実行できるようにします。ステートメント select を実行し、行のセット全体に対して同じ操作を実行する代わりに。
2) カーソル位置に基づいてテーブル内の行を削除および更新する機能を提供します。
3) カーソルは実際には、セット指向データベース管理システム (RDBMS) と行指向プログラミングの間のブリッジとして機能し、これら 2 つの処理メソッドがカーソルを介して通信できるようにします。
3.カーソル
の使用については、このマルチ カーソルの利点について説明しましたが、ここではカーソルの謎を個人的に明らかにします。
カーソルの使用順序: カーソルの宣言、カーソルのオープン、データの読み取り、カーソルのクローズ、カーソルの削除
CREATE PROCEDURE PK_Test
AS
--変数の宣言
declare @O_ID nvarchar(20)
@A_Salary float を宣言します
--カーソル mycursor を宣言します、
AddSalary から O_ID,A_Salary を選択するための mycursor カーソルを宣言します
--カーソルを開きます
mycurs または
を開きます--から削除カーソル データ(select文のパラメータの数はカーソルから取り出した変数名と同じである必要があります)を先ほど宣言した変数に代入します
次にmycursorから@O_ID,@A_Salaryにフェッチ
/*//判定 カーソルのステータス
//0 フェッチステートメントは成功しました
//-1 フェッチステートメントは失敗したか、行が結果セットにありません
//-2 フェッチされた行は存在*/
--何度もループしますカーソルを読み取り、@O_ID、@A_Salaryの値を取得します
while (@@fetch_status=0)
--読み取りを開始します
begin
-- @O_ID、@A_Salary を既知の使用として好きなだけ扱います。
--カーソルを使用して毎回取得する値を表示します
print 'カーソルはデータの一部を正常に取得しました'
print @O_ID
print @A_Salary
--カーソルを使用してレコードを取得します
mycursor から @O_ID,@A_Salary に次をフェッチします
end
--カーソルを閉じる
mycursorを閉じる
--mycursorを解放します
mycursorを解放します
GO
使い方of Top
select Top 5 lngWorkID,strWorkName,strExecHumanName,strBeginDate
from worklist where lngExecHumanID= @lngUserID
SQL ステートメントを使用して取得したレコードの最初の 5 行を取得します