ユーザー定義関数内でのsp_executesqlプロシージャの使用

このQ&Aのポイント
  • SQLServer2005を使用している場合、ユーザー定義関数内でsp_executesqlを実行することはできません。
  • sp_executesqlはマスターデータベースの拡張プロシージャに位置づけられているため、関数内で実行できません。
  • 一方、関数内で実行可能な拡張ストアドプロシージャや関数を使用することはできます。
回答を見る
  • ベストアンサー

ユーザー定義関数内でのsp_executesqlプロシージャの使用

SQLServer2005を使用しています。 今、ユーザー定義関数を作成していて、クエリアナライザにて動作を検証しています。 ユーザー定義関数内で、sp_executesqlを実行しようとすると、 「サーバー : メッセージ 557、レベル 16、状態 2、プロシージャ F_GET_DAY、行 26 関数内から実行できるのは関数と拡張ストアド プロシージャだけです。」 というエラーが出ます。 sp_executesqlは、マスターデータベースの拡張プロシージャに位置づけられているので、実行可能だと思ったのですが・・・。 同じく、マスターデータベースの拡張プロシージャにである「sp_oacreate」の実行を試してみると、関数内で実行できました。 sp_executesqlは、関数内では実行できないのでしょうか。

  • you25
  • お礼率40% (2/5)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

ANO.1です。 >>スカラ値関数ではOKのようです(補足で頂いたSQLもOKです)。 >ここのところを再度ご教授願えないでしょうか。 なるほど納得です。私はEXECUTEしてました。 例: DECLARE @ret int EXEC @ret = dbo.F_GET_DAY 通常、関数は、SELECTでも使用しますので、 そのあたり検証すべきでした。 申し訳ありません。 SELECT, PRINTともNGで、EXECUTE はOKでした。 拡張ストアドの種類や関数の実行の仕方など、 SQLServerが判断して実行可否を決定しているのですね。 で、その判断基準は明記されておらず (関数の設計基準はありますが)、 実行してみないことにはわからないようです。 またまた勉強になりました。

you25
質問者

お礼

ご回答、ありがとうございます! >SQLServerが判断して実行可否を決定しているのですね。 >で、その判断基準は明記されておらず >(関数の設計基準はありますが)、 >実行してみないことにはわからないようです。 エラーメッセージでは可能なような気がしてしまったので、どうなのかな、と思いましたが、SELECT、PRINTの場合はやはりNGなのですね、、、 しかし、この辺の判断基準は明確にしていただきたいものですね。 ありがとうございます、ファンクションの奥深さを教えていただきました☆

その他の回答 (2)

回答No.2

ANo.1です。 私の理解不足でした。現象が確認できました。 テーブル値関数内で、「sp_executesql」を実行すると、 「関数内から実行できるのは・・」エラーが発生しました。 作成されているユーザー関数はテーブル値関数ではないですか? スカラ値関数ではOKのようです(補足で頂いたSQLもOKです)。 ヘルプには関数内で「sp_executesql」は実行可能であるかのように 書かれております。 テーブル値関数で、NGなのかは、明記されておりませんでした。 (ストアドでSELECTの結果を返すときに、 ストアド内で「EXECUTE」を利用していない場合は、 関数に置き換え可能であるとの記述は見つけましたが。) おそらく関数とは、 1.スカラ関数は値を返す。 2.テーブル値関数はビューでは実現できない形で結果を得る、  すなわち、パラメータを渡せたり、テーブル変数に対して  更新などの処理を行い、結果を返す。 もので、それ以上のことを行うときは、 エラーが発生するかもしれないので、 ストアドプロシージャを利用しましょう ということになるのでしょうか。 勉強になりました。

you25
質問者

補足

ご回答ありがとうございます! なるほど、テーブル値関数ではNGなのですね、ヘルプではそこまで読み取れないとのこと、大変貴重なご意見いただきました。ありがとうございます。 しかし、私の場合はそれ以前の問題のようです、、、 私が今回使用しているのはスカラ値関数です。 1.ファンクション作成 CREATE FUNCTION F_test () RETURNS int AS BEGIN DECLARE @SQL NVARCHAR(4000) --SQL作成 SET @SQL = N'INSERT INTO T_CAL VALUES (''2006/12/04'',1)' --実行 EXECUTE sp_executesql @SQL --戻り値 RETURN (1) END 2.クエリアナライザより、実行 select dbo.F_test() とした場合、「サーバー : メッセージ 557、レベル 16、状態 2、プロシージャ F_test、行 10 関数内から実行できるのは関数と拡張ストアド プロシージャだけです。」 というエラーが発生します。 >スカラ値関数ではOKのようです(補足で頂いたSQLもOKです)。 ここのところを再度ご教授願えないでしょうか。

回答No.1

関数内からsp_executesqlは実行できます。 sp_executesqlに渡している文字列内に実行できないコマンドがあるとかではないですか? ログインユーザーの権限とsp_executesqlに渡している文字列の内容を可能な限り教えて頂けますか?

you25
質問者

補足

tasokarewa様 ご意見ありがとうございます! 1.sp_executesqlに渡している文字列の内容は、テスト的に簡単なINSERT文としています。 SET @SQL = N'INSERT INTO T_CAL VALUES (''2006/12/04'',1)' EXECUTE sp_executesql @SQL 上記は、プロシージャでは実行可能ですが、ファンクションではエラーがでます。 2.ログインユーザの権限というところは怪しいのですが、、、 ・クエリアナライザでは、「おそらく全てのデータベースに接続できる」と思っているsaユーザにて接続しています。 ・実行可能なプロシージャ、実行不可能なファンクションとも、所有者dboで作成されています。 ・・・補足回答になっているでしょうか、、、 関数内からsp_executesqlを実行している例がネット上、どうしても見つかりません。(何れもストアドプロシージャか無名プロシージャです。。。) できれば、実行可能なファンクションサンプルを教えていただけないでしょうか。

関連するQ&A

  • T-SQLの sp_executesql について

    SQL-Serverでストアドプロシージャを作っています。 EXEC sp_executesql で検索結果をテーブル型変数に格納したいですができるのでしょうか。動的にSQLを発行し、結果を格納する必要がありますのでEXEC sp_executesqlを使わざる得ない状況です。下記にそのサンプルがあります。 Declare @tblAA Table(NO int) declare @strSQL nVarChar(1000) set @strSQL = '' set @strSQL = @strSQL + ' Insert into @tblAA' set @strSQL = @strSQL + ' Select NO from TBLBango' EXEC sp_executesql @strSQL ,N'@tblAA table(No int) OUTPUT', @tblAA OUTPUT Select * from @tblAA これを実行すろと「変数 '@tblAA' を宣言する必要があります。」というエラーがでます。 解決方法を分かる方教えてください。

  • PostgreSQL(8.4.2)のユーザ定義関数(ストアドプロシージ

    PostgreSQL(8.4.2)のユーザ定義関数(ストアドプロシージャ)を、 ODBC経由でVisualStudio2005から利用したいのですが、 サーバーエクスプローラーからユーザ定義関数を参照することが出来なくて悩んでいます。 ユーザ定義関数はpgAdminIIIで作成しました。 cse(Common SQL Environment)などのフリーのツールからは問題なく参照できます。 VisualStudioにユーザ定義関数として認識させるための何かおまじない的な物が必要なのでしょうか。 それともPostgreSQLとVisualStudioとの相性が悪いのでしょうか。 なおユーザ定義関数以外であるテーブルやビューは、 サーバーエクスプローラーから参照できます。

  • ユーザーが定義したストアドプロシージャ一覧の取得

    SQL Server 2005で、 db内のストアドプロシージャ一覧を取得したいと思っています。 select o.* from syscomments c , sysobjects o where c.id = o.id and o.type='P' order by o.name といったように記述すれば一覧は取得できるようですが、 これだとシステムストアドプロシージャも表示されてしまいます。 ユーザーで定義したストアドプロシージャのみ取得したいのですが、可能でしょうか? 何か良い手段をご存じの方がいらっしゃいましたらアドバイス頂けますと嬉しいです。 どうぞよろしくお願いいたします。

  • ストアドプロシージャ

    MySQLでストアドプロシージャを使おうと思ったのですが、root権限でないと実行も定義もできません。 他のユーザーに権限を与えるにはどうしたらいいでしょうか? userテーブルのExecute_privの値は関係ありますか?

    • ベストアンサー
    • MySQL
  • Accessプロジェクト ストアドプロシージャでのデータ更新

    AccessのMDBをADPへ作り変えています。 MDBの更新クエリーの場合、「レコードの更新」欄に更新したい値を記述します。たとえば、ユーザー定義関数を使っている場合は、ユーザー関数名([○○○]) ・・・。 これと同じことを、ADPのストアドプロシージャで行う場合はどのようにすればよいのでしょうか? スツアドプロシージャは「デザイナを使用してストアドプロシージャを作成する」を使って作成しています。ここで、「新しい値」欄に ユーザー関数名(○○○) と記述すると、 ”ADOエラー:"ユーザー関数名"は関数名として認識されません” となります。 初めてADPを使用するのでよくわかりません。 以上、よろしくお願いします。

  • プロシージャの実行

    ストアドプロシージャを実行させようと、プロシージャに実行権限を付与しました。(grant execute ・・・) その後実行しようとすると、 オブジェクト aaa_proc、データベース bbb、所有者 ccc について EXECUTE パーミッションが拒否されました とエラーになります。 aaa_proc は プロシージャ名。 bbbは プロシージャを書くときに use bbb と書いてるデータベースの名前。 cccは ユーザ名としてください。 他に何の権限を与えてやればいいのか、どなたかか教えてください。 宜しくおねがいします。

  • 【 困 】 ストアドプロシージャ

    OS:WIN2000 DB:SQLServer2000 下記のストアドプロシージャを作成しました。 BULK INSERTを使っています。 引数でCSVファイルのパスを渡そうとしています。 「エラー170:行5: '@Query'の近くに無効な構文があります。」 というエラーになってしまいます。 5行目にあるFromの次に変数を書くには、どうしたらいいのでしょうか? CREATE proc SP_BULK_INSERT @Query char(100) AS BULK INSERT T_顧客マスタ FROM @Query WITH (FIELDTERMINATOR = ',') GO

  • ユーザからADPのストアドプロシージャを修正できないようにする

    Microsoft Access2000のADPを通じて、MSDEを操作するデータベースを作成しました。 社内のユーザに ADPを変換したADEファイルを配付しようとしていますが、このままでは、ユーザが不用意にストアドプロシージャを修正してしまう恐れがあります。 ユーザからADEのストアドプロシージャを修正できないようにする方法はありませんでしょうか?

  • データベースのユーザ定義関数について

    PHP4.3.1、MySQL4.1.13を使用して、Webアプリケーションを製作しております。 幾つかの参考書籍やこれら情報に関するWebなどを見ていますと、後々データベースが変更になった時を考え、それぞれのデータベース用の関数を利用せずユーザ定義関数で処理した方が良いと書かれていました。 ただ、データーベースの処理と言っても様々な処理があると思いますし、それら全てをユーザ定義関数で置き換えなくてはならないのかな?と疑問(迷い)を感じております。 皆様は、どの様にされていますでしょうか?または、どの様に考えたら良いでしょうか?プログラミングの基本的な事かもしれませんが、どなたかご教授いただけないでしょうか? 宜しくお願いします。

    • ベストアンサー
    • PHP
  • ストアドプロシージャで外部プログラムを起動するには?

    こんにちは。 SQL Serverから外部プログラムを呼び出すストアドプロシージャを作りたいと思っていますがなかなか上手くいきません。 データベースの内容が変わったときに(INSERT,DELETE等で)特定の外部プログラムを実行するストアドプロシージャを作りたいと思っています。 (SQL Serverに関してまったくの素人なので言葉に誤りがあるかもしれません) 外部プログラムを呼び出す機能として、拡張ストアドプロシージャでxp_cmdshellというものがあるらしいのですが、sysadminユーザしか使うことが出来ず、セキュリティ上にも問題があるとのことなので、xp_cmdshellを使わずに外部プログラムを呼び出す方法を探しています。 具体的な方法、ソース等ありましたら、教えてもらえないでしょうか? また、そんなこと出来ないと言ったことでも教えてもらえると助かります。 現在の環境 Windows XP Professional SQL Server 2005 Developer Edition 宜しくお願いいたします。