DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ストアドのパラメータ

環境/言語:[WinXP+SQL2000+.Net1.1+Vb.Net2003]
分類:[.NET]

はじめまして
Vb.Net2003
OS:WinXP
SQLServer2000

Vb.Netからストアドを実行しているのですが、
’PR_LOGINには@USER_IDを指定して下さい’
とMsgが出力されます。
引数は指定してるつもり?なのに

ストアド
CREATE PROCEDURE PR_LOGIN
(
@USER_ID INTEGER OUTPUT,
@USER_PW VARCHAR(50) OUTPUT
)
AS

DECLARE CUR_LOGIN CURSOR SCROLL
FOR
SELECT USER_ID,USER_PW FROM LOGIN_USER

OPEN CUR_LOGIN

FETCH NEXT FROM CUR_LOGIN INTO @USER_ID,@USER_PW

WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM CUR_LOGIN INTO @USER_ID,@USER_PW
END
CLOSE CUR_LOGIN
RETURN



VB.NET
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim SQLcd As New SqlCommand
Dim PRM1 As SqlParameter
Dim PRM2 As SqlParameter

'接続を開きます
Try
ClassAccessSQL.OpenCnSQL("Host", "DB", "user", "pass")

SQLcd.CommandText = "pr_login"
SQLcd.Connection = ClassAccessSQL.SQLcn
SQLcd.CommandType = CommandType.StoredProcedure

PRM1 = SQLcd.Parameters.Add("@USER_ID", SqlDbType.Int, ParameterDirection.Output)
PRM2 = SQLcd.Parameters.Add("@USER_PW", SqlDbType.Int, ParameterDirection.Output)

SQLcd.ExecuteNonQuery()


Me.TextBox1.Text = SQLcd.Parameters("@user_id").Value
Me.TextBox2.Text = SQLcd.Parameters("@user_pw").Value

Catch ex As Exception

 MsgBox(ex.ToString)

Finally

ClassAccessSQL.CloseSQL(False)

End Try

End Sub
やりたいことはFethcでレコードを取得しTextBoxに表示させたいのです。
Fethcは参考書片手にはじめて挑戦してみましたが
上記のように上手くいきません。
ご教授願います。
by リコ
> PRM1 = SQLcd.Parameters.Add("@USER_ID", SqlDbType.Int, ParameterDirection.Output)

こういう指定の仕方ってできましたっけ? MSDNを見る限り、このようなオーバーロードはないようです。VB.NETだとParameterDirection.Outputを自動的にIntegerにキャストしてるのかな?

ところで、念のために確認しますが、上記プログラムの目的を達成するだけならストアドプロシージャ内でカーソルを使う必要はありませんが、カーソルを使うための練習と考えてよいのでしょうか?
返信ありがとうございます。

ところで、念のために確認しますが、上記プログラムの目的を達成するだけならストアドプロシージャ内でカーソルを使う必要はありませんが、カーソルを使うための練習と考えてよいのでしょうか?

↑そのとおりです。
カーソルの仕組みが知りたくて・・・
PosionとかADOのPageなどもありますが、
なるべくSQLServer側で動作させたいと思っています。
昨日から書籍を購入して色々ためしているのですが、
ストアド側の問題か?VB.NET側の問題か?
すらわかりません。
2006/06/19(Mon) 12:26:27 編集(投稿者)

> ↑そのとおりです。

了解です。

> 昨日から書籍を購入して色々ためしているのですが、
> ストアド側の問題か?VB.NET側の問題か?
> すらわかりません。

ここら辺のページが参考になると思います。

▼単一行エンティティを返すデータ操作
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdndotnet/htm/DataOperationsReturningSingleRowEntities.asp

▼行のセットに対するデータ操作
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdndotnet/htm/DataOperationsonSetsofRows.asp

また、VS2003をお使いのようですので、ストアドプロシージャを右クリックして、「ストアドプロシージャにステップイン」を行えば、行単位にストアドプロシージャをデバッグすることができます。
このデバッグを行うには、masterデータベースの拡張ストアドプロシージャ内の、sp_sdidebugの実行が許可されていなければなりません。許可されていなければ、そのようなメッセージが表示されるはずなので、それに従って下さい。
返信ありがとうございます。

> ▼単一行エンティティを返すデータ操作
> http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdndotnet/htm/DataOperationsReturningSingleRowEntities.asp
>
> ▼行のセットに対するデータ操作
> http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdndotnet/htm/DataOperationsonSetsofRows.asp
>
> また、VS2003をお使いのようですので、ストアドプロシージャを右クリックして、「ストアドプロシージャにステップイン」を行えば、行単位にストアドプロシージャをデバッグすることができます。
> このデバッグを行うには、masterデータベースの拡張ストアドプロシージャ内の、sp_sdidebugの実行が許可されていなければなりません。許可されていなければ、そのようなメッセージが表示されるはずなので、それに従って下さい。

早速、上記を試してみたいと思ってます。
ただ今日は忙しいので、結果は後日ご報告させていただきます。
trapemiya さん
お待たせしました!
ストアドの変数の定義に=NULLとしパラメータも明示的に宣言したらOKでした!
若干ストアド側もVB.NETもコーディング変更しました。
URLとても参考になりました。
それにストアドがデバックできるなんて初めて知りました。
リコ的に最高です!!
ありがとうございます。
それにしてもtrapemiya さん なぜVS2003ってわかったんですか???
ももももしや!ハッキング!!!


ストアド
CREATE PROCEDURE PR_LOGIN
(
@USER_ID VARCHAR(50) =null OUTPUT,  --ココ
@USER_PW VARCHAR(50)=null OUTPUT   --ココ
)
AS

DECLARE CUR_LOGIN CURSOR SCROLL
FOR
SELECT USER_ID,USER_PW FROM LOGIN_USER

OPEN CUR_LOGIN

FETCH NEXT FROM CUR_LOGIN INTO @USER_ID,@USER_PW

WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM CUR_LOGIN INTO @USER_ID,@USER_PW
END
CLOSE CUR_LOGIN
deallocate CUR_LOGIN
RETURN

VB.NET
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim SQLcd As New SqlCommand
Dim prm1 As New SqlParameter
Dim prm2 As New SqlParameter
Try


SQLcd.CommandText = "pr_login"
SQLcd.Connection = ClassAccessSQL.SQLcn
SQLcd.CommandType = CommandType.StoredProcedure

'接続を開きます
ClassAccessSQL.OpenCnSQL("host", "database", "user", "pass", True)

'パラメータの定義 明示的に宣言する。
prm1 = SQLcd.Parameters.Add("@user_id", SqlDbType.VarChar, 50)
prm1.Direction = ParameterDirection.Output
prm2 = SQLcd.Parameters.Add("@user_PW", SqlDbType.VarChar, 50)
prm2.Direction = ParameterDirection.Output


SQLcd.ExecuteNonQuery()

'テキストボックスに表示。
Me.TextBox1.Text = SQLcd.Parameters("@user_id").Value
Me.TextBox2.Text = SQLcd.Parameters("@user_pw").Value
ClassAccessSQL.SQLcn.Close()

Catch ex As Exception
MsgBox(ex.ToString)
End Try

End Sub

しかし・・・
次なる疑問が湧き出てきました。
現在位置を覚えさせて自由に戻ったり次へレコードをすすめるには?
と思ったのですが、参考書には載ってないし・・・
どなたか知っている方、ご教授お願いいたします。
自分でもがんばってみます。
すみません!少し間違ってたので再投稿します。
trapemiya さん
お待たせしました!
ストアドの変数の定義に=NULLとしパラメータも明示的に宣言したらOKでした!
若干ストアド側もVB.NETもコーディング変更しました。
URLとても参考になりました。
それにストアドがデバックできるなんて初めて知りました。
リコ的に最高です!!
ありがとうございます。
それにしてもtrapemiya さん なぜVS2003ってわかったんですか???
ももももしや!ハッキング!!!


ストアド
CREATE PROCEDURE PR_LOGIN
(
@USER_ID VARCHAR(50) =null OUTPUT,  --ココ
@USER_PW VARCHAR(50)=null OUTPUT   --ココ
)
AS

DECLARE CUR_LOGIN CURSOR SCROLL
FOR
SELECT USER_ID,USER_PW FROM LOGIN_USER

OPEN CUR_LOGIN

FETCH NEXT FROM CUR_LOGIN INTO @USER_ID,@USER_PW

WHILE @@FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM CUR_LOGIN INTO @USER_ID,@USER_PW
END
CLOSE CUR_LOGIN
deallocate CUR_LOGIN
RETURN

VB.NET
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim SQLcd As New SqlCommand
Dim prm1 As New SqlParameter
Dim prm2 As New SqlParameter
Try


SQLcd.CommandText = "pr_login"
SQLcd.Connection = ClassAccessSQL.SQLcn
SQLcd.CommandType = CommandType.StoredProcedure

'接続を開きます
ClassAccessSQL.OpenCnSQL("host", "database", "user", "pass", True)

'パラメータの定義 明示的に宣言する。
prm1 = SQLcd.Parameters.Add("@user_id", SqlDbType.VarChar, 50)
prm1.Direction = ParameterDirection.Output
prm2 = SQLcd.Parameters.Add("@user_PW", SqlDbType.VarChar, 50)
prm2.Direction = ParameterDirection.Output


SQLcd.ExecuteNonQuery()

'テキストボックスに表示。
Me.TextBox1.Text = SQLcd.Parameters("@user_id").Value
Me.TextBox2.Text = SQLcd.Parameters("@user_pw").Value
ClassAccessSQL.SQLcn.Close()

'ココが間違ってました!
Catch ex As SqlException
MsgBox(ex.ToString)
Catch ex As Exception
MsgBox(ex.ToString)
Finally
ClassAccessSQL.SQLcn.Close()
End Try

End Sub

しかし・・・
次なる疑問が湧き出てきました。
現在位置を覚えさせて自由に戻ったり次へレコードをすすめるには?
と思ったのですが、参考書には載ってないし・・・
どなたか知っている方、ご教授お願いいたします。
自分でもがんばってみます。
> リコ的に最高です!!

お役に立ってよかったです。

> それにしてもtrapemiya さん なぜVS2003ってわかったんですか???

vb.net2003って、一番最初に書いてありましたもの。

> 次なる疑問が湧き出てきました。
> 現在位置を覚えさせて自由に戻ったり次へレコードをすすめるには?
> と思ったのですが、参考書には載ってないし・・・

これはストアドプロシージャ内でのお話なんでしょうか?であれば、とりあえず以下のページを参考にしてやるしかないと思います。ただ、あまり複雑になってくると、クライアント側でやった方がパフォーマンス的に有利になると思います。
SQL server 2005だと、SQL CLRなんていうのもありますね。

フェッチとスクロール
http://msdn2.microsoft.com/ja-jp/library/ms187881.aspx
早速のご返信ありがとうございます!
>vb.net2003って、一番最初に書いてありましたもの。
↑vsとは書いてなかったものですから・・・
どうしてVBではなくvisual studioとわかったのかな?と思ったものですから。

> これはストアドプロシージャ内でのお話なんでしょうか?であれば、とりあえず以下のページを参考にしてやるしかないと思います。ただ、あまり複雑になってくると、クライアント側でやった方がパフォーマンス的に有利になると思います。
↑そうです。ストアド内のことです。ちなみにtrapemiya さんならどういう思考をお持ちですか?たとえば会計伝票(PCAとかOBCとかTKC)とかって一件づつ進んだり戻ったりして修正したいデータに到達したら'修正ボタン'をClickした瞬間にロックしてます。
リコ的にはこの動きはきっとカーソルを使用してるんじゃないかな?って思ったんです。それ以外のお勧めな方法があれば、よろしければ教えていただけないでしょうか?もちろんヒントだけでも結構です。
リコ的にはクライアントとなると前述のposionやADOのpageはたまたmove系を利用してTimeStamp列で判断するくらいしか思いつきません。他におすすめの方法があれば是非!

> SQL server 2005だと、SQL CLRなんていうのもありますね。
↑SQL SERVER2005すごいほしい!
でもVS.NET2003+SQLServer2000+WindowsServer2003の購入資金で余裕なかったです。ゆくゆくは絶対買う。
(てかプログラマでもない普通の事務の新入社員なんですけどね!でも好き!!)

> フェッチとスクロール
> http://msdn2.microsoft.com/ja-jp/library/ms187881.aspx
ご多忙なはずなのにありがたいサイト探してくれたんですね!(涙)
早速試してみます。
リコもいつかは回答者側になるぞぉー
> ↑vsとは書いてなかったものですから・・・
> どうしてVBではなくvisual studioとわかったのかな?と思ったものですから。

そっか。確かに、そうですね。私はVisual StudioはInterDevの頃から使い始めたので、VB.NET単体という発想が出てきませんでした。(^^;

> リコ的にはこの動きはきっとカーソルを使用してるんじゃないかな?って思ったんです。それ以外のお勧めな方法があれば、よろしければ教えていただけないでしょうか?もちろんヒントだけでも結構です。

そのアプリケーションが要求する要件にもよると思いますので、以下、一般論です。
データベースはデータをそこから直接出し入れすることが基本として設計されています。したがって、ADO.NETから直接SQL文を投げようが、ストアドでSQL文を投げようが、SQLによってデータを直接操作することを基本とします。ところがカーソルですが、カーソルはデータベースからどのような値を持ってくるかということが定義されているオブジェクトです。当然、カーソルを通してデータベースからデータを引き出すことになり、パフォーマンス的によくありません。
繰り返しになりますが、データベースはSQLによりデータを直接操作できることが基本であり、それが大きな魅力です。必要がない限り、わざわざカーソル経由で読むことはありません。

さて、伝票処理ですが、基本は、前に行くにも後ろに行くにもSQLを発行してデータを得て、一件ずつデータを更新することです。もちろん、一覧で修正したいという場合もあるでしょう。そのような場合は大抵が表形式になりますから、データテーブルに読み込んで、DataGrid辺りで編集ということになるでしょう。このデータテーブルへの変更は最終的にデータベースへ書き戻しますから、多くの人が同時に使うようなシステムの場合は、同時実行の問題が発生します。ロックなどの問題やどのようなタイミングでデータベースにデータを更新に行くのかなど、そのシステムに合わせて設計する必要があります。

> でもVS.NET2003+SQLServer2000+WindowsServer2003の購入資金で余裕なかったです。ゆくゆくは絶対買う。
> (てかプログラマでもない普通の事務の新入社員なんですけどね!でも好き!!)

いいですね。その意気込み!がんばって下さい。ネットに多くの先生がいますので、大丈夫ですよ。一歩ずつでも進みましょう。
trapemiya さん力強い回答ありがとうございます。

> いいですね。その意気込み!がんばって下さい。ネットに多くの先生がいますので、大丈夫ですよ。一歩ずつでも進みましょう。

この言葉を胸に励みにがんばります。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板