私は関数とストアドプロシージャをかなり長い間学習してきましたが、関数やストアドプロシージャを使用する理由と時期がわかりません。彼らは私には同じように見えます、それはおそらく私がそれについて少し初心者だからです。
誰かが理由を教えてもらえますか?
私は関数とストアドプロシージャをかなり長い間学習してきましたが、関数やストアドプロシージャを使用する理由と時期がわかりません。彼らは私には同じように見えます、それはおそらく私がそれについて少し初心者だからです。
誰かが理由を教えてもらえますか?
回答:
関数は計算された値であり、永続的な環境変更を実行できませんSQL Server
(つまり、許可されていない、INSERT
またはUPDATE
ステートメントが許可されています)。
関数SQL
は、スカラー値を返す場合はステートメント内でインラインで使用でき、結果セットを返す場合は結合できます。
回答をまとめたコメントから注目に値するポイント。@Sean K Andersonに感謝:
関数は値を返す必要があり、パラメーター(引数)として受け取ったデータを変更できないという点で、コンピューターサイエンスの定義に従います。関数は何も変更できません。少なくとも1つのパラメーターが必要で、値を返す必要があります。ストアドプロシージャはパラメータを持つ必要がなく、データベースオブジェクトを変更でき、値を返す必要はありません。
SQL
ストアドプロシージャから関数を呼び出す 方法と、ストアドプロシージャの代わりに関数を使用する場合。
こんにちは。今日は、ストアドプロシージャをいつ使用し、いつ関数を使用するかについて説明します。単純なチームの場合いくつかの値を計算したい場合、単一の値を返すため、必要ありません。
https://programmingtechtutorial.blogspot.com/2020/01/when-use-storeprocedure-and-when-use.html
SPとUDFの違いは次のとおりです。
+---------------------------------+----------------------------------------+
| Stored Procedure (SP) | Function (UDF - User Defined |
| | Function) |
+---------------------------------+----------------------------------------+
| SP can return zero , single or | Function must return a single value |
| multiple values. | (which may be a scalar or a table). |
+---------------------------------+----------------------------------------+
| We can use transaction in SP. | We can't use transaction in UDF. |
+---------------------------------+----------------------------------------+
| SP can have input/output | Only input parameter. |
| parameter. | |
+---------------------------------+----------------------------------------+
| We can call function from SP. | We can't call SP from function. |
+---------------------------------+----------------------------------------+
| We can't use SP in SELECT/ | We can use UDF in SELECT/ WHERE/ |
| WHERE/ HAVING statement. | HAVING statement. |
+---------------------------------+----------------------------------------+
| We can use exception handling | We can't use Try-Catch block in UDF. |
| using Try-Catch block in SP. | |
+---------------------------------+----------------------------------------+
関数とストアドプロシージャは別の目的で使用されます。これは最良の類推ではありませんが、関数は文字通り、任意のプログラミング言語で使用する他の関数と見なすことができますが、ストアドプロシージャは、個々のプログラムやバッチスクリプトに似ています。
関数には通常、出力とオプションで入力があります。出力は、他の機能(SQL Serverが内蔵例えば等DATEDIFF、LENなど)またはSQLクエリの述語としての入力として使用することができる-例えば、SELECT a, b, dbo.MyFunction(c) FROM table
若しくはSELECT a, b, c FROM table WHERE a = dbo.MyFunc(c)
。
ストアドプロシージャは、SQLクエリをトランザクションにバインドし、外界とのインターフェースをとるために使用されます。ADO.NETなどのフレームワークは、関数を直接呼び出すことはできませんが、ストアドプロシージャを直接呼び出すことはできます。
ただし、関数には隠れた危険があります。それらは誤用され、かなり厄介なパフォーマンスの問題を引き起こす可能性があります。次のクエリを検討してください。
SELECT * FROM dbo.MyTable WHERE col1 = dbo.MyFunction(col2)
MyFunctionは次のように宣言されています。
CREATE FUNCTION MyFunction (@someValue INTEGER) RETURNS INTEGER
AS
BEGIN
DECLARE @retval INTEGER
SELECT localValue
FROM dbo.localToNationalMapTable
WHERE nationalValue = @someValue
RETURN @retval
END
ここでは、テーブルMyTableのすべての行に対して関数MyFunctionが呼び出されます。MyTableに1000行ある場合、それはデータベースに対する別の1000アドホッククエリです。同様に、列仕様で指定されたときに関数が呼び出された場合、SELECTによって返された各行に対して関数が呼び出されます。
したがって、関数の作成には注意が必要です。関数内のテーブルからSELECTを実行する場合は、親ストアドプロシージャのJOINまたは他のSQL構文(CASE ... WHEN ... ELSE ...など)を使用して、より適切に実行できるかどうかを自問する必要があります。終わり)。
SELECT * from dbo.MyTableValuedFunction()
。一方、Sprocsは、に設定SqlCommand.CommandType
することにより、ADO.NETで直接呼び出すことができますCommandType.StoredProcedure
。
ストアドプロシージャとユーザー定義関数の違い:
RAISEERROR
OR @@ERROR
はUDFでは許可されていません。GETDATE()
、UDFでは使用できません。GETDATE()
関数で使用できます。非決定論のピボットは良いものではありません。
他のSQLステートメントで使用する値を計算して返す場合は、ユーザー定義関数を記述します。複雑なSQLステートメントのセットをグループ化する場合は、代わりにストアドプロシージャを作成します。結局のところ、これらは2つのまったく異なる使用例です!
STORE PROCEDURE FUNCTION (USER DEFINED FUNCTION)
* Procedure can return 0, single or | * Function can return only single value
multiple values. |
|
* Procedure can have input, output | * Function can have only input
parameters. | parameters.
|
* Procedure cannot be called from | * Functions can be called from
function. | procedure.
|
* Procedure allows select as well as | * Function allows only select statement
DML statement in it. | in it.
|
* Exception can be handled by | * Try-catch block cannot be used in a
try-catch block in a procedure. | function.
|
* We can go for transaction management| * We can't go for transaction
in procedure. | management in function.
|
* Procedure cannot be utilized in a | * Function can be embedded in a select
select statement | statement.
|
* Procedure can affect the state | * Function can not affect the state
of database means it can perform | of database means it can not
CRUD operation on database. | perform CRUD operation on
| database.
|
* Procedure can use temporary tables. | * Function can not use
| temporary tables.
|
* Procedure can alter the server | * Function can not alter the
environment parameters. | environment parameters.
|
* Procedure can use when we want | * Function can use when we want
instead is to group a possibly- | to compute and return a value
complex set of SQL statements. | for use in other SQL
| statements.
基本的な違い
関数は値を返す必要がありますが、ストアドプロシージャではオプションです(プロシージャは値0またはnを返すことができます)。
関数は入力パラメータのみを持つことができますが、プロシージャは入力/出力パラメータを持つことができます。
関数は必須の入力パラメーターを1つ取りますが、ストアード・プロシージャーはoからnの入力パラメーターを取る場合があります。
関数はプロシージャから呼び出すことができますが、プロシージャは関数から呼び出すことはできません。
事前差異
プロシージャではSELECTとDML(INSERT / UPDATE / DELETE)ステートメントを使用できますが、関数ではSELECTステートメントのみを使用できます。
プロシージャはSELECTステートメントでは使用できませんが、関数はSELECTステートメントに埋め込むことができます。
ストアドプロシージャはSQLステートメントでWHERE / HAVING / SELECTセクションのどこにも使用できませんが、関数は使用できます。
テーブルを返す関数は、別の行セットとして扱うことができます。これは、他のテーブルとのJOINで使用できます。
インライン関数は、パラメーターを取り、JOINやその他の行セット操作で使用できるビューと考えることができます。
例外はプロシージャのtry-catchブロックで処理できますが、try-catchブロックは関数では使用できません。
手続きではトランザクション管理に行くことができますが、関数では行くことができません。
Returns
キーワードを介して実行する必要があり、スカラーまたはテーブル型でなければなりません) 、ただしストアドプロシージャはオプションで次を返すことができます:a)ステートメントInt
による1 タイプの結果コードReturn
および/またはb)キーワードによる1+パラメータ(Cursor
タイプを含む)Output
および/またはc)Select
ステートメントによる1+行セット。1行セットのみの場合が返された場合、「Insert Into」ステートメントの「execute_statement」引数として使用できます。」
ユーザー定義関数は、SQLサーバープログラマが利用できる重要なツールです。あなたはそのようなSQLステートメントでそれをインラインで使うことができます
SELECT a, lookupValue(b), c FROM customers
どこlookupValue
がUDFになります。ストアドプロシージャを使用する場合、この種の機能は使用できません。同時に、UDF内では特定のことを実行できません。ここで覚えておくべき基本的なことは、UDFのことです。
ストアドプロシージャはこれらのことを実行できます。
私にとって、UDFのインライン使用はUDFの最も重要な使用法です。
ストアドプロシージャ はスクリプトとして使用されます。これらは一連のコマンドを実行し、特定の時間に実行するようにスケジュールすることができます。通常、INSERT、UPDATE、DELETEなどの複数のDMLステートメント、またはSELECTを実行します。
関数 はメソッドとして使用されます。何かを渡すと、結果が返されます。小さくて高速でなければなりません-その場でそれを行います。通常、SELECTステートメントで使用されます。
ストアドプロシージャ:
EXEC
or EXECUTE
ステートメントを使用して呼び出す必要があります。OUT
パラメーターは使用できません。関数:
レコードの選択にのみ使用できます。ただし、次のように、標準SQL内から非常に簡単に呼び出すことができます。
SELECT dbo.functionname('Parameter1')
または
SELECT Name, dbo.Functionname('Parameter1') FROM sysObjects
単純な再利用可能な選択操作の場合、関数はコードを簡略化できます。JOIN
関数での句の使用には注意してください。関数にJOIN
句があり、複数の結果を返す別の選択ステートメントからそれを呼び出す場合、その関数呼び出しは、結果セットで返される行ごとにJOIN
それらのテーブルをまとめて行います。したがって、一部のロジックを簡略化するのに役立ちますが、適切に使用されない場合、パフォーマンスのボトルネックになる可能性もあります。
OUT
パラメータを使用して値を返します。ユーザー定義関数。
ストアドプロシージャ
カーソルのようなSQL Server関数は、最後の武器として使用するためのものです。それらにはパフォーマンスの問題があるため、テーブル値関数の使用は可能な限り避ける必要があります。パフォーマンスとは、中流ハードウェア上のサーバーでホストされている1,000,000を超えるレコードを持つテーブルのことです。それ以外の場合は、関数によって引き起こされるパフォーマンスへの影響を心配する必要はありません。
詳細については、以下を参照してください。 http //databases.aspfaq.com/database/should-i-use-a-view-a-stored-procedure-or-a-user-defined-function.html
これが、ストアドプロシージャよりも関数を優先する実用的な理由です。別のストアドプロシージャの結果を必要とするストアドプロシージャがある場合は、insert-execステートメントを使用する必要があります。つまり、一時テーブルを作成し、exec
ステートメントを使用して、ストアドプロシージャの結果を一時テーブルに挿入する必要があります。乱雑です。これに関する1つの問題は、insert-execをネストできないことです。です。
他のストアード・プロシージャーを呼び出すストアード・プロシージャーに行き詰まっている場合、これに遭遇する可能性があります。ネストされたストアドプロシージャがデータセットを返すだけの場合は、テーブル値関数で置き換えることができ、このエラーは発生しなくなります。
(これは、データベースからビジネスロジックを除外する必要があるもう1つの理由です)
関数はselect文で使用できますが、プロシージャでは使用できません。
ストアドプロシージャは入力パラメーターと出力パラメーターの両方を受け取りますが、関数は入力パラメーターのみを受け取ります。
関数は、プロシージャのようにtext、ntext、image、timestamp型の値を返すことはできません。
関数はcreate tableでユーザー定義のデータ型として使用できますが、プロシージャは使用できません。
***例:-作成 table <tablename>(name varchar(10),salary getsal(name))
ここで、getsalはユーザー定義関数であり、給与タイプを返します。テーブルが作成されると、給与タイプにストレージが割り当てられず、getsal関数も実行されませんが、このテーブルからいくつかの値をフェッチすると、getsal関数が実行され、 return Typeが結果セットとして返されます。
これは非常に古い質問であることに気づきましたが、どの回答にも重要な側面の1つはありません。クエリプランへのインライン化です。
関数は...
スカラー:
CREATE FUNCTION ... RETURNS scalar_type AS BEGIN ... END
複数ステートメントのテーブル値:
CREATE FUNCTION ... RETURNS @r TABLE(...) AS BEGIN ... END
インラインテーブル値:
CREATE FUNCTION ... RETURNS TABLE AS RETURN SELECT ...
3番目の種類(インラインテーブル値)は、クエリオプティマイザーによって本質的に(パラメーター化された)ビューとして扱われます。つまり、クエリからの関数の参照は、関数のSQL本文のコピーと貼り付け(実際にはコピーと貼り付けなし)に似ています。次の利点に:
上記により、特に複数のレベルの関数を組み合わせる場合に、パフォーマンスを大幅に節約できる可能性があります。
注:SQL Server 2019では、何らかの形式のスカラー関数のインライン化も導入されるようです。
SQL Serverでは、関数とストアドプロシージャは2種類のエンティティです。
関数: SQL Serverデータベースでは、いくつかのアクションを実行するために関数が使用され、アクションはすぐに結果を返します。関数には2つのタイプがあります。
システム定義
ユーザー定義の
ストアドプロシージャ: SQL Serverでは、ストアドプロシージャはサーバーに格納され、ゼロ、単一、および複数の値を返すことができます。ストアドプロシージャには次の2つのタイプがあります。