927

関数とストアドプロシージャをかなり長い間学習してきましたが、関数またはストアドプロシージャを使用する理由と時期がわかりません。彼らは私には同じように見えます、おそらく私はそれについてちょっと初心者だからです。

誰かが理由を教えてもらえますか?

4

21 に答える 21

781

関数は計算された値であり、永続的な環境変更を実行することはできませんSQL Server(つまり、noINSERTまたはUPDATEステートメントが許可されます)。

関数SQLは、スカラー値を返す場合はステートメントでインラインで使用でき、結果セットを返す場合は結合できます。

答えをまとめたコメントから注目すべき点。@Sean K Andersonに感謝します:

関数は、値を返さなければならず、パラメーター(引数)として受け取るデータを変更できないという点で、コンピューターサイエンスの定義に従います。関数は何も変更できず、少なくとも1つのパラメーターが必要であり、値を返す必要があります。ストアドプロシージャはパラメータを持っている必要はなく、データベースオブジェクトを変更でき、値を返す必要もありません。

于 2009-07-24T19:42:14.013 に答える
720

The difference between SP and UDF is listed below:

Stored Procedure (SP) Function (UDF - User Defined)
SP can return zero, single or multiple values. Function must return a single value (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 parameter. Only input parameter.
We can call function from SP. We can't call SP from function.
We can't use SP in SELECT/ WHERE/ HAVING statement. We can use UDF in SELECT/ WHERE/ HAVING statement.
We can use exception handling using Try-Catch block in SP. We can't use Try-Catch block in UDF.
于 2012-10-15T17:00:55.163 に答える
196

関数とストアドプロシージャは別々の目的を果たします。これは最良の例えではありませんが、関数は文字通り、プログラミング言語で使用する他の関数と同じように表示できますが、ストアドプロシージャは、個々のプログラムやバッチスクリプトに似ています。

関数には通常、出力とオプションで入力があります。次に、出力を別の関数(DATEDIFF、LENなどの組み込みのSQL Server)への入力として、または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

ここで何が起こるかというと、関数MyFunctionがテーブルMyTableのすべての行に対して呼び出されるということです。MyTableに1000行ある場合、それはデータベースに対する別の1000アドホッククエリです。同様に、列仕様で指定されたときに関数が呼び出されると、SELECTによって返される行ごとに関数が呼び出されます。

したがって、関数の記述には注意が必要です。関数内のテーブルからSELECTを実行する場合は、親ストアドプロシージャのJOINまたはその他のSQL構造(CASE ... WHEN ... ELSE ...など)を使用してSELECTを実行する方がよいかどうかを自問する必要があります。終わり)。

于 2009-07-24T20:06:18.973 に答える
67

ストアドプロシージャとユーザー定義関数の違い:

  • ストアドプロシージャは、Selectステートメントでは使用できません。
  • ストアドプロシージャは、遅延名前解決をサポートします。
  • ストアドプロシージャは通常、ビジネスロジックを実行するために使用されます。
  • ストアドプロシージャは、任意のデータ型を返すことができます。
  • ストアドプロシージャは、ユーザー定義関数よりも多くの入力パラメーターを受け入れることができます。ストアドプロシージャには、最大21,000の入力パラメータを含めることができます。
  • ストアドプロシージャは動的SQLを実行できます。
  • ストアドプロシージャはエラー処理をサポートします。
  • 非決定論的関数は、ストアドプロシージャで使用できます。

  • ユーザー定義関数は、Selectステートメントで使用できます。
  • ユーザー定義関数は、遅延名前解決をサポートしていません。
  • ユーザー定義関数は、通常、計算に使用されます。
  • ユーザー定義関数は値を返す必要があります。
  • ユーザー定義関数は画像を返すことができません。
  • ユーザー定義関数は、ストアード・プロシージャーよりも少ない数の入力パラメーターを受け入れます。UDFには、最大1,023個の入力パラメーターを含めることができます。
  • 一時テーブルは、ユーザー定義関数では使用できません。
  • ユーザー定義関数は動的SQLを実行できません。
  • ユーザー定義関数はエラー処理をサポートしていません。 RAISEERRORまたは@@ERROR、UDFでは許可されていません。
  • 非決定論的関数はUDFでは使用できません。たとえばGETDATE()、UDFでは使用できません。
于 2013-05-02T09:52:10.927 に答える
58

他のSQLステートメントで使用する値を計算して返す場合は、ユーザー定義関数を記述します。代わりに、複雑な可能性のあるSQLステートメントのセットをグループ化する必要がある場合は、ストアドプロシージャを記述します。結局のところ、これらは2つのまったく異なるユースケースです。

于 2009-07-24T19:42:36.743 に答える
55
ストアドプロシージャ 関数(ユーザー定義関数)
プロシージャは0、単一または複数の値を返すことができます 関数は単一の値のみを返すことができます
プロシージャには、入力パラメータと出力パラメータを含めることができます 関数は入力パラメーターのみを持つことができます
関数からプロシージャを呼び出すことはできません プロシージャから関数を呼び出すことができます
プロシージャでは、DMLステートメントだけでなくselectステートメントも使用できます 関数はその中のselectステートメントのみを許可します
例外は、プロシージャのtry-catchブロックで処理できます Try-catchブロックは関数で使用できません
手順でトランザクション管理に行くことができます 機能的にトランザクション管理に行くことはできません
プロシージャをselectステートメントで使用することはできません 関数はselectステートメントに埋め込むことができます
手順はデータベースの状態に影響を与える可能性があります。つまり、データベースに対してCRUD操作を実行できます。 関数がデータベースの状態に影響を与えることができないということは、データベースに対してCRUD操作を実行できないことを意味します
プロシージャは一時テーブルを使用できます 関数は一時テーブルを使用できません
手順により、サーバー環境パラメーターが変更される可能性があります 関数は環境パラメータを変更できません
代わりに、複雑な可能性のあるSQLステートメントのセットをグループ化する場合に使用できるプロシージャ 関数は、他のSQLステートメントで使用する値を計算して返す場合に使用できます
于 2018-07-07T11:57:33.397 に答える
28

基本的な違い

関数は値を返す必要がありますが、ストアドプロシージャではオプションです(プロシージャはゼロまたはn個の値を返すことができます)。

関数はその入力パラメーターのみを持つことができますが、プロシージャは入力/出力パラメーターを持つことができます。

関数は1つの入力パラメーターを取りますが、これは必須ですが、ストアード・プロシージャーはoからnの入力パラメーターを取る場合があります。

関数はプロシージャから呼び出すことができますが、プロシージャは関数から呼び出すことはできません。

事前差

プロシージャではSELECTステートメントとDML(INSERT / UPDATE / DELETE)ステートメントを使用できますが、ファンクションではSELECTステートメントのみを使用できます。

プロシージャはSELECTステートメントで使用できませんが、FunctionはSELECTステートメントに埋め込むことができます。

ストアドプロシージャは、WHERE / HAVING / SELECTセクションのSQLステートメントでは使用できませんが、関数では使用できます。

テーブルを返す関数は、別の行セットとして扱うことができます。これは、他のテーブルとのJOINで使用できます。

インライン関数は、パラメーターを受け取り、JOINやその他の行セット操作で使用できるビューと考えることができます。

例外は、プロシージャのtry-catchブロックで処理できますが、関数ではtry-catchブロックは使用できません。

手続きではトランザクション管理に進むことができますが、機能では行くことができません。

ソース

于 2014-02-28T10:55:26.520 に答える
21

ユーザー定義関数は、SQLサーバープログラマーが利用できる重要なツールです。次のようなSQLステートメントでインラインで使用できます。

SELECT a, lookupValue(b), c FROM customers 

lookupValueUDFはどこになりますか。ストアドプロシージャを使用する場合、この種の機能は使用できません。同時に、UDF内で特定のことを行うことはできません。ここで覚えておくべき基本的なことは、UDFの次のことです。

  • 永続的な変更を作成することはできません
  • データを変更できません

ストアドプロシージャはそれらのことを実行できます。

私にとって、UDFのインライン使用はUDFの最も重要な使用法です。

于 2009-07-24T20:04:21.737 に答える
17

ストアドプロシージャ はスクリプトとして使用されます。彼らはあなたのために一連のコマンドを実行し、あなたはそれらを特定の時間に実行するようにスケジュールすることができます。通常、INSERT、UPDATE、DELETEなどの複数のDMLステートメント、またはSELECTを実行します。

関数 はメソッドとして使用されます。あなたはそれに何かを渡すと、それは結果を返します。小さくて速いはずです-その場でそれを行います。通常、SELECTステートメントで使用されます。

于 2015-03-13T19:55:56.157 に答える
8

ストアドプロシージャ:

  • SQLServerのミニチュアプログラムのようなものです。
  • selectステートメントのように単純な場合もあれば、データベース内の複数のテーブルからデータを追加、削除、更新、および/または読み取る長いスクリプトのように複雑な場合もあります。
  • (ループとカーソルを実装できます。どちらも、データに対してより小さな結果または行ごとの操作を処理できます。)
  • EXECまたはEXECUTEステートメントを使用して呼び出す必要があります。
  • OUTテーブル変数を返しますが、パラメータは使用できません。
  • トランザクションをサポートします。

働き:

  • データベースの更新、削除、またはレコードの追加には使用できません。
  • 単一の値またはテーブル値を返すだけです。
  • レコードの選択にのみ使用できます。ただし、次のように、標準SQL内から非常に簡単に呼び出すことができます。

    SELECT dbo.functionname('Parameter1')
    

    また

    SELECT Name, dbo.Functionname('Parameter1') FROM sysObjects
    
  • 単純な再利用可能な選択操作の場合、関数はコードを単純化できます。JOIN関数で句を使用する場合は注意が必要です。関数にJOIN句があり、複数の結果を返す別のselectステートメントからそれを呼び出す場合、その関数呼び出しは、結果セットで返される行ごとJOINに それらのテーブルをまとめて呼び出します。したがって、これらは一部のロジックを単純化するのに役立ちますが、適切に使用されていない場合、パフォーマンスのボトルネックになる可能性もあります。

  • パラメータを使用して値を返しOUTます。
  • トランザクションをサポートしていません。
于 2014-04-29T11:56:17.300 に答える
8

ユーザー定義関数。

  1. 関数は値を返す必要があります。
  2. Selectステートメントのみを許可し、DMLステートメントの使用は許可しません。
  3. 入力パラメーターのみを許可し、出力パラメーターはサポートしません。
  4. try-catchブロックを使用することはできません。
  5. 関数内でのトランザクションは許可されていません。
  6. 使用できるのはテーブル変数のみで、一時テーブルの使用は許可されません。
  7. ストアドプロシージャを関数から呼び出すことはできません。
  8. 関数はselectステートメントから呼び出すことができます。
  9. UDFは、結果セットとして結合句で使用できます。

ストアドプロシージャ

  1. ストアドプロシージャは値を返す場合と返さない場合があります。
  2. selectステートメントと、挿入、更新、削除などのDMLステートメントを含めることができます
  3. 入力パラメータと出力パラメータの両方を持つことができます。
  4. 例外処理には、trycatchブロックを使用できます。
  5. ストアドプロシージャ内でトランザクションを使用できます。
  6. テーブル変数と一時テーブルの両方を使用できます。
  7. ストアドプロシージャは関数を呼び出すことができます。
  8. Select / Where/Havingなどのステートメントからプロシージャを呼び出すことはできません。Execute / Execステートメントを使用して、ストアドプロシージャを呼び出し/実行できます。
  9. プロシージャはJoin句では使用できません
于 2019-07-29T14:58:22.800 に答える
7

カーソルのようなSQLServer関数は、最後の武器として使用することを目的としています。それらにはパフォーマンスの問題があるため、テーブル値関数の使用は可能な限り避ける必要があります。パフォーマンスについて話すことは、ミドルクラスのハードウェア上のサーバーでホストされている1,000,000を超えるレコードを持つテーブルについて話すことです。それ以外の場合は、関数によって引き起こされるパフォーマンスの低下について心配する必要はありません。

  1. 関数を使用して結果セットを外部コード(ADO.Netなど)に返さないでください
  2. ビュー/ストアドプロシージャの組み合わせを可能な限り使用します。DTA(Database Tuning Adviser)が提供する提案(インデックス付きビューや統計など)を使用して、将来のパフォーマンスの向上の問題から回復できます。

詳細については、http: //databases.aspfaq.com/database/should-i-use-a-view-a-stored-procedure-or-a-user-defined-function.htmlを参照してください。

于 2009-12-09T20:27:49.080 に答える
6

次のポイントが役立つ可能性があるものをいつ使用するかを決定するには-

  1. ストアドプロシージャはテーブル変数を返すことができませんが、関数はそれを行うことができます。

  2. ストアドプロシージャを使用してサーバー環境パラメータを変更できますが、関数を使用する場合は変更できません。

乾杯

于 2009-07-24T19:54:50.087 に答える
4

単一の値を返す関数から始めます。良い点は、頻繁に使用するコードを関数に入れて、結果セットの列として返すことができることです。

次に、パラメータ化された都市のリストの関数を使用できます。dbo.GetCitiesIn( "NY")これは結合として使用できるテーブルを返します。

これは、コードを整理する方法です。いつ再利用可能で、いつそれが時間の無駄であるかを知ることは、試行錯誤と経験によってのみ得られるものです。

また、SQLServerでは関数を使用することをお勧めします。それらはより高速で、非常に強力です。インラインおよび直接選択。使いすぎないように注意してください。

于 2013-09-16T20:28:10.657 に答える
4

ストアドプロシージャよりも関数を優先する実際的な理由は次のとおりです。別のストアドプロシージャの結果を必要とするストアドプロシージャがある場合は、insert-execステートメントを使用する必要があります。これは、一時テーブルを作成し、execステートメントを使用してストアドプロシージャの結果を一時テーブルに挿入する必要があることを意味します。散らかっています。これに関する1つの問題は、insert-execをネストできないことです。

他のストアドプロシージャを呼び出すストアドプロシージャで立ち往生している場合は、これに遭遇する可能性があります。ネストされたストアドプロシージャが単にデータセットを返す場合は、テーブル値関数に置き換えることができ、このエラーは発生しなくなります。

これは、ビジネスロジックをデータベースから除外する必要があるもう1つの理由です

于 2016-05-31T17:57:26.397 に答える
3

これは非常に古い質問だと思いますが、どの回答にも重要な側面が1つはありません。それは、クエリプランにインライン化することです。

関数は...

  1. スカラー:

    CREATE FUNCTION ... RETURNS scalar_type AS BEGIN ... END

  2. マルチステートメントテーブル値:

    CREATE FUNCTION ... RETURNS @r TABLE(...) AS BEGIN ... END

  3. インラインテーブル値:

    CREATE FUNCTION ... RETURNS TABLE AS RETURN SELECT ...

3番目の種類(インラインテーブル値)は、クエリオプティマイザーによって基本的に(パラメーター化された)ビューとして扱われます。つまり、クエリから関数を参照することは、関数のSQL本体を(実際にコピーして貼り付けることなく)コピーして貼り付けることに似ています。次の利点があります。

  • クエリプランナーは、他のサブクエリと同じようにインライン関数の実行を最適化できます(たとえば、未使用の列を削除する、述語をプッシュダウンする、さまざまなJOIN戦略を選択するなど)。
  • 複数のインライン関数を組み合わせると、最初の関数から次の関数にフィードする前に結果を具体化する必要はありません。

上記は、特に複数のレベルの機能を組み合わせる場合に、潜在的に大幅なパフォーマンスの低下につながる可能性があります。


注:SQL Server 2019では、何らかの形式のスカラー関数のインライン化も導入されるようです。

于 2019-01-18T06:52:04.857 に答える
3

Mssqlストアドプロシージャと関数:

ここに画像の説明を入力してください

于 2020-06-16T21:57:16.790 に答える
2
  • ストアドプロシージャ用ではないのに、Functionが値を返すことは必須です。
  • SDFでのみ受け入れられるステートメントを選択しますが、DMLステートメントは必要ありません。
  • ストアドプロシージャは、DMLステートメントだけでなくすべてのステートメントを受け入れます。
  • UDFは入力のみを許可し、出力は許可しません。
  • ストアドプロシージャでは、入力と出力の両方が可能です。
  • キャッチブロックはUDFでは使用できませんが、ストアドプロシージャでは使用できます。
  • UDFの関数ではトランザクションは許可されていませんが、ストアドプロシージャでは許可されています。
  • UDFで使用できるのはテーブル変数のみで、一時テーブルは使用できません。
  • ストアドプロシージャでは、テーブル変数と一時テーブルの両方を使用できます。
  • UDFでは、ストアドプロシージャを関数から呼び出すことはできませんが、ストアドプロシージャでは関数を呼び出すことができます。
  • UDFは結合句で使用されますが、ストアドプロシージャは結合句では使用できません。
  • ストアドプロシージャは常にゼロに戻ることができます。それどころか、UDFには、あらかじめ決められたポイントに戻らなければならない値があります。
于 2013-10-15T12:19:13.263 に答える
1
  • 関数はselectステートメントで使用できますが、プロシージャでは使用できません。

  • ストアドプロシージャは入力パラメータと出力パラメータの両方を取りますが、関数は入力パラメータのみを取ります。

  • 関数は、プロシージャができる場合、タイプtext、ntext、image、およびタイムスタンプの値を返すことはできません。

  • 関数は、テーブルの作成でユーザー定義のデータ型として使用できますが、プロシージャは使用できません。

***例:-作成table <tablename>(name varchar(10),salary getsal(name))

ここで、getsalは給与タイプを返すユーザー定義関数であり、テーブルが作成されると、給与タイプにストレージが割り当てられず、getsal関数も実行されませんが、このテーブルからいくつかの値をフェッチすると、getsal関数getが実行され、 returnTypeが結果セットとして返されます。

于 2012-07-21T19:33:57.043 に答える
0

一般に、パフォーマンスにはストアドプロシージャを使用する方が適しています。たとえば、以前のバージョンのSQL Serverでは、関数をJOIN条件にすると、カーディナリティの推定値は1(SQL 2012より前)および100(SQL2012より後およびSQL2017より前)であり、エンジンは不適切な実行プランを生成する可能性があります。

また、WHERE句に入れると、SQLエンジンが不正な実行プランを生成する可能性があります。

SQL 2017で、Microsoftはより正確な見積もりを生成するためにインターリーブ実行と呼ばれる機能を導入しましたが、ストアドプロシージャは依然として最良のソリューションです。

詳細については、JoeSackの次の記事を参照して くださいhttps://techcommunity.microsoft.com/t5/sql-server/introducing-interleaved-execution-for-multi-statement-table/ba-p/385417

于 2020-07-05T22:07:25.613 に答える
-2

SQL Serverでは、関数とストアドプロシージャは2つの異なるタイプのエンティティです。

関数: SQL Serverデータベースでは、関数はいくつかのアクションを実行するために使用され、アクションはすぐに結果を返します。関数には2つのタイプがあります。

  1. システム定義

  2. ユーザー定義の

ストアドプロシージャ: SQL Serverでは、ストアドプロシージャはサーバーに格納され、ゼロ、単一、および複数の値を返すことができます。ストアドプロシージャには次の2つのタイプがあります。

  1. システムストアドプロシージャ
  2. ユーザー定義の手順
于 2015-12-17T07:19:06.543 に答える