2011-12-23 21 views
1

Stack Exchangeデータエクスプローラーで関数を作成/呼び出ししようとしています。関数がSQL Serverで呼び出されない理由

私が今作成したこの機能をなぜ呼び出さないのですか?

-- Get Post with Best Comment on Site 
-- Gets the Post with the Best Comment on the Site and Associated Data 

CREATE FUNCTION typeOfPost 
(@PostId int(11)) 
RETURNS varchar(30) 
AS 
BEGIN 
declare @PostTypeId int(3) 
select @PostTypeId = (SELECT PostTypeId FROM posts WHERE PostId = @PostId) 
return (SELECT Name FROM PostTypes WHERE Id = @PostTypeId) 
end 

SELECT PostId, typeOfPost(PostId) AS [Post Type] 
FROM comments 
WHERE Score = (
SELECT max(Score) 
FROM comments 
);​​​​​​​​​​​ 

それは与える:

"SELECT" "typeOfPostを" 関数名に組み込まれて認識されていません。

SQL Serverの関数呼び出しの例を見て、前面に「.dbo」がたくさんあることがわかりました。私がこれを置くと、私はこれを得る:

キーワード 'SELECT'の近くに構文が正しくない。

誰も私の機能に何か問題があると説明できますか?

+0

あなたの関数を呼び出すには、 'dbo.typeOfPost(PostId)'を使ってみてください。何らかの理由で、関数呼び出しにスキーマ名が必要です。なぜ私は現時点で覚えていないのですか? [スキーマ名なしでユーザー定義関数を呼び出すことは可能ですか?](http://stackoverflow.com/questions/502949/is-it-possible-to-call-a-user-defined-function-without-スキーマ名) – Beno

+0

@Beno - afaikは、システム関数とユーザー定義関数を区別します。そして、お尻の王様の痛みになる:) – MatBailie

+0

INTとINT(3)をINTに変えてみてください。 SQL ServerではINTデータ型のサイズを指定できません – Sparky

答えて

3

コードは有効です(int.sのサイズは無く、Posts.Idの正しい列名)。

CREATE FUNCTION typeOfPost 
(@PostId int) 
RETURNS varchar(30) 
AS 
BEGIN 
declare @PostTypeId int 
select @PostTypeId = (SELECT PostTypeId FROM posts WHERE Id = @PostId) 
return (SELECT Name FROM PostTypes WHERE Id = @PostTypeId) 
end 
​ 

そして、あなたが得る:

Error: CREATE FUNCTION permission denied in database 'StackOverflow.Exported'.\ 

あなたはStackOverflowのデータエクスプローラでオブジェクトを作成することはできません。あなたが望むことができる最高のオブジェクトの作成は、テーブル変数です。

さらに、エラーが発生する理由は、バッチが構文チェックされているときに関数が存在しないため、2番目のステートメントが機能しないということです。従来のSSMS環境では、バッチで関数を作成し、別のバッチで関数を使用して実行します。これは、GOバッチセパレータを使用して1つのファイルで実行できます。これはSSMSやその他のツールの機能です(オプションで上書きすることもできます)。

さらに、解決しようとしている問題は、通常、スカラー関数で解決された問題ではありません(もちろん、データを取得するためにテーブルを個別にトリップする問題ではありません)。通常、これはJOINを使って非常に簡単に処理できます.JOINは、ブロック・ボックスとして扱われるスカラー関数よりもオプティマイザにとってよりアクセスしやすくなります。

0

関数のスキーマ名の前に関数の接頭辞を付けます。たぶんdbo.と異なるかもしれません。

SELECT PostId, dbo.typeOfPost(PostId) AS [Post Type] 
FROM comments 
WHERE Score = (
SELECT max(Score) 
FROM comments 
);​​​​​​​​​​​ 
+0

「選択に近い構文が正しくありません」というエラーが発生しました –

+0

@AlexCoplan - 関数スクリプトを単独で実行し、成功したかどうかを確認します。その後、独自のクエリを実行します。 *私は*、現時点で言えば、クエリはあなたの関数内の別のコマンドとして解釈されていると思います。これは、関数がクエリではなくエラーを作成していることを意味します。 * [これは、あなたが機能を変更(またはドロップして再作成)することを含むかもしれません。] * – MatBailie

+0

私は今ベッドに入っています。そうでなければ、他の誰かがあなたを助けることを願っています:) – MatBailie

0

次のような関数呼び出しなしで同じ結果を得ることができます:私はあなたのエラーメッセージがSQLを受け入れないINT(XX)の構文、によって引き起こされると考え

SELECT TOP 1 c.postId,Pt.Name as [Post Type] 
FROM comments c 
JOIN posts p ON c.PostID=p.postID 
JOIN PostTypes Pt on Pt.postTypeID=p.PostTypeId 
ORDER BY c.Score DESC 

。また、関数定義とその関数を使用するSELECT句の間にGOキーワードを追加してください。

関連する問題