create_function
create_function — 匿名関数(ラムダ形式)を作成する
説明
string create_function ( string args, string code )指定したパラメータにより匿名関数を作成し、その関数のユニークな名前を返します。 通常、argsには、シングルクオートで括った文字列を 指定し、code の場合も同様に指定することが推奨されます。 シングルクオートで括った文字列を使用する理由は、パース時に変数名を保護するためです。 ダブルクオートを使用した場合には、\$avarのように変数名を エスケープする必要があります。
(例えば、)実行時に取得した情報から関数を作成する際にこの関数を使用することが可能です。 例 708. create_function()により匿名関数を作成する
<?php
$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
echo "New anonymous function: $newfunc\n";
echo $newfunc(2, M_E) . "\n";
// outputs
// New anonymous function: lambda_1
// ln(2) + ln(2.718281828459) = 1.6931471805599
?>
もしくは、パラメータリストに一連の処理を行うことができる一般的なハンドラ関数を 定義できます。
例 709. create_function() で一般的な処理関数を作成する
<?php
function process($var1, $var2, $farr)
{
foreach ($farr as $f) {
echo $f($var1, $var2) . "\n";
}
}
// create a bunch of math functions
$f1 = 'if ($a >=0) {return "b*a^2 = ".$b*sqrt($a);} else {return false;}';
$f2 = "return \"min(b^2+a, a^2,b) = \".min(\$a*\$a+\$b,\$b*\$b+\$a);";
$f3 = 'if ($a > 0 && $b != 0) {return "ln(a)/b = ".log($a)/$b; } else { return false; }';
$farr = array(
create_function('$x,$y', 'return "some trig: ".(sin($x) + $x*cos($y));'),
create_function('$x,$y', 'return "a hypotenuse: ".sqrt($x*$x + $y*$y);'),
create_function('$a,$b', $f1),
create_function('$a,$b', $f2),
create_function('$a,$b', $f3)
);
echo "\nUsing the first array of anonymous functions\n";
echo "parameters: 2.3445, M_PI\n";
process(2.3445, M_PI, $farr);
// now make a bunch of string processing functions
$garr = array(
create_function('$b,$a', 'if (strncmp($a, $b, 3) == 0) return "** \"$a\" '.
'and \"$b\"\n** Look the same to me! (looking at the first 3 chars)";'),
create_function('$a,$b', '; return "CRCs: " . crc32($a) . " , ".crc32(b);'),
create_function('$a,$b', '; return "similar(a,b) = " . similar_text($a, $b, &$p) . "($p%)";')
);
echo "\nUsing the second array of anonymous functions\n";
process("Twas brilling and the slithy toves", "Twas the night", $garr);
?>
and when you run the code above, the output will be:
Using the first array of anonymous functions parameters: 2.3445, M_PI some trig: -1.6291725057799 a hypotenuse: 3.9199852871011 b*a^2 = 4.8103313314525 min(b^2+a, a^2,b) = 8.6382729035898 ln(a/b) = 0.27122299212594 Using the second array of anonymous functions ** "Twas the night" and "Twas brilling and the slithy toves" ** Look the same to me! (looking at the first 3 chars) CRCs: -725381282 , 1908338681 similar(a,b) = 11(45.833333333333%)
しかし、恐らくラムダ形式の(匿名)関数の最も一般的な使用法は、 array_walk() または usort() を使用する場合にようにコールバック関数を作成する場合でしょう。
例 710. コールバック関数として匿名関数を使用する
<?php
$av = array("the ", "a ", "that ", "this ");
array_walk($av, create_function('&$v,$k', '$v = $v . "mango";'));
print_r($av);
?>
outputs:
Array ( [0] => the mango [1] => a mango [2] => that mango [3] => this mango )文字列の配列は短いものから長いものへ並べられました。
<?php
$sv = array("small", "larger", "a big string", "it is a string thing");
print_r($sv);
?>
outputs:
Array ( [0] => small [1] => larger [2] => a big string [3] => it is a string thing )長い文字列から短い文字列へソートされました。
<?php
usort($sv, create_function('$a,$b','return strlen($b) - strlen($a);'));
print_r($sv);
?>
outputs:
Array ( [0] => it is a string thing [1] => a big string [2] => larger [3] => small )
ストアドプロシージャ
(create_function から転送)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/02/19 20:02 UTC 版)
ナビゲーションに移動 検索に移動![]() | この記事は検証可能な参考文献や出典が全く示されていないか、不十分です。2017年9月) ( |
ストアドプロシージャ (英:Stored Procedure) は、リレーショナルデータベース管理システム(RDBMS)にアクセスするアプリケーションで利用できるサブルーチンである。このようなプロシージャは、データベースのデータ辞書に格納されている。
ストアドプロシージャの用途としては、データの検証(データベースへの統合)やアクセス制御の仕組みなどがある。さらに、ストアドプロシージャは、もともとアプリケーションに実装されていたロジックを統合し、一元化することができる。時間とメモリを節約するために、複数のSQL文の実行を必要とする大規模または複雑な処理をストアドプロシージャに保存し、すべてのアプリケーションはそのプロシージャを呼び出すことができる。ストアドプロシージャの中から別のストアドプロシージャを実行することで、ネストされたストアドプロシージャを使用することができる。
ストアドプロシージャは結果セット、つまりSELECT
文の結果を返すことがある。このような結果セットは、カーソル、他のストアドプロシージャ、結果セットロケータの関連付け、またはアプリケーションによって処理することができる。ストアドプロシージャは、データを処理するための宣言された変数や、テーブルの複数の行をループするためのカーソルを含むこともできる。ストアドプロシージャのフロー制御文には、通常、IF
、WHILE
、LOOP
、REPEAT
、CASE
文などがある。ストアドプロシージャは、変数の宣言方法と宣言場所によって、変数を受け取って結果を返したり、変数を変更して結果を返したりすることができる。
実装
ストアドプロシージャは、ユーザー定義関数(UDF)に似ている。大きな違いは、UDFはSQL文の中で他の式と同様に使用できるのに対し、ストアドプロシージャはCALL
文を使って呼び出さなければならないことである。
CALL procedure(...)
または
EXECUTE procedure(...)
ストアドプロシージャの正確で正しい実装は、データベースシステムによって異なる。ほとんどの主要なデータベースベンダーは、何らかの形でストアドプロシージャをサポートしている。ストアドプロシージャは、データベースシステムに応じて、SQL、Java、C、C++など、さまざまなプログラミング言語で実装することができる。SQL以外の言語で書かれたストアドプロシージャは、それ自体がSQL文を実行することも、しないこともある。
ストアドプロシージャの採用が進んだことで、SQL:1999とSQL:2003の標準SQL/PSMという部分で、SQL言語に手続き的な要素が導入されることになり、SQLは命令型プログラミング言語となった。ほとんどのデータベースシステムは,SQL/PSMを超える独自の拡張やベンダ固有の拡張を提供している.Javaストアドプロシージャの標準仕様は、SQL/JRTと同様に存在する。
データベースシステム | 実装言語 |
---|---|
CUBRID | Java |
IBM DB2 | SQL PL( SQL/PSM標準に近い)またはJava |
Firebird | PSQL(FyracleはOracleのPL / SQLの一部もサポート) |
Informix | Java |
Interbase | ストアドプロシージャとトリガー言語 |
Microsoft SQL Server | Transact-SQLおよびさまざまな.NET Framework言語 |
MySQL 、 MariaDB | SQL/PSM標準に厳密に準拠した独自のストアドプロシージャ |
NuoDB | SQLまたはJava |
OpenLink Virtuoso | Virtuoso SQLプロシージャ(VSP); [1] Java、C、およびその他のプログラミング言語を介して拡張可能 |
Oracle | PL / SQLまたはJava |
PostgreSQL | PL/pgSQLは、PL / PerlやPL / PHPなどの独自の関数言語を使用することも可能 |
SAP HANA | SQLScriptまたはR |
SAP ASE | Transact-SQL |
SAP SQL Anywhere | Transact-SQL 、Watcom SQL |
SQLite | サポートされていない |
静的SQLとの比較
オーバーヘッド
ストアドプロシージャ文は直接データベースに格納されるため、ソフトウェアアプリケーションがインライン(動的)SQLクエリをデータベースに送信する状況で通常必要となるコンパイルのオーバーヘッドのすべてまたは一部を削除することができる。(ただし、ほとんどのデータベースシステムは、動的SQL文の反復的なコンパイルを避けるために、ステートメントキャッシュや他の方法を実装している)。また、プリコンパイルされたSQLをある程度回避できる一方で、SQL文のすべての引数がコンパイル時に提供されないため、最適な実行プランを作成するための複雑さが増す。特定のデータベースの実装や構成によっては、ストアドプロシージャと一般的なクエリやユーザー定義関数を比較した場合、性能に差が出ることがある。
ネットワークトラフィックの回避
ストアドプロシージャの大きな利点は、データベースエンジン内で直接実行できることである。本番システムでは、プロシージャは専用のデータベースサーバーで実行され、アクセスされるデータに直接アクセスできるのが一般的である。この利点は、ネットワーク通信コストを完全に回避できることである。これは、一連の複雑なSQL文の場合に、より重要になる。
ビジネスロジックのカプセル化
ストアドプロシージャは、プログラマがビジネスロジックをAPIとしてデータベースに埋め込むことができるため、データ管理を簡素化し、クライアントプログラムの別の場所でロジックをエンコードする必要性を低減することができる。その結果、欠陥のあるクライアントプログラムによるデータ破損の可能性を低くすることができる。データベースシステムは、ストアドプロシージャの助けを借りて、データの整合性と一貫性を確保することができる。
アクセス権の委譲
多くのシステムでは、ストアドプロシージャに、そのプロシージャを実行するユーザーが直接持っていないデータベースへのアクセス権を与えることができる。
SQLインジェクション攻撃からの保護
ストアドプロシージャは、インジェクション攻撃から保護するために使用することができる。ストアドプロシージャのパラメータは、攻撃者がSQLコマンドを挿入しても、データとして扱われる。また、DBMSによっては、パラメータの型をチェックするものもある。しかし、ストアドプロシージャが入力されたデータを使って動的SQLを生成する場合、適切な予防措置が取られない限り、SQLインジェクションの危険性があることに変わりはない。
デメリット
- ストアドプロシージャ言語は、ベンダーに依存することが多い。データベースベンダーを変更する場合、通常、既存のストアドプロシージャを書き換える必要がある。
- ストアドプロシージャの変更は、他のコードに比べてバージョン管理システム内で追跡することが困難である。プロジェクト履歴に保存するためには、変更をスクリプトとして再現しなければならず、プロシージャの差分をマージして正しく追跡するのが難しい場合がある。
- ストアドプロシージャのエラーは、アプリケーションIDEでのコンパイルやビルドのステップの一部として捕らえることができない。ストアドプロシージャが行方不明になったり、誤って削除されたりした場合も同様である。
- ストアドプロシージャ言語は、ベンダーによって洗練されたレベルが異なる。
- 例えば、PostgresのpgpsqlはMicrosoftのT-SQLよりも多くの言語機能(特に拡張機能による)を持っている。
- ストアドプロシージャの作成とデバッグのためのツールサポートは、他のプログラミング言語ほど充実していないことが多いが、これはベンダーや言語によって異なる。
- 例えば、PL/SQLとT-SQLには専用の IDE とデバッガがある。PL/PgSQLは、様々なIDEからデバッグすることができる。
脚注
- ^ “Chapter 11. SQL Procedure Language Guide”. OpenLink documentation. 2019年9月11日閲覧。
関連項目
- SQL/PSM
- PL/pgSQL
- PL/SQL
- Transact-SQL
- PSQL
- create_functionのページへのリンク