プロが教えるわが家の防犯対策術!

SQL Serverのストアド中でUPDATEを実行すると
OUTパラメータの値が取得できなくなってしまいます。

何か制約などあるのでしょうか?
わかる方よろしくお願いします。

1.UPDATE文をコメントアウトすると取得できます。
2.UPDATEは正常に実行されています。

/**参考ソース**/
/**
下記プログラムは、引数で取得した文字列に
連番テーブルの値をインクリメントした値と
結合しOUTパラメータに、連番テーブルには、
インクリメント結果をセットしています。
**/

CREATE procedure xml_get_document_seq
@inDate varchar(14),
@outSeq varchar(18) output
as
begin
declare@Workvarchar(4)
declare@Seqvarchar(18)
declare@Numberdecimal(5)
declare@SeqDocvarchar(18)

if not exists(SELECT SEQ
FROM XML_DOCUMENT_SEQ) begin
INSERT INTO XML_DOCUMENT_SEQ(SEQ)
VALUES(0)
end

set @Seq= ISNULL(@inDate,'')

SELECT @Number = SEQ
FROM XML_DOCUMENT_SEQ

set @Number = @Number + 1
if @Number > 9999 begin
 set @Number = 1
end

set @Work= ISNULL(convert(varchar,@Number),'')
set @SeqDoc= @Seq
+ replicate('0', 4 - datalength(@Work))
+ @Work

UPDATE XML_DOCUMENT_SEQ
SET SEQ = @Number

Set @outSeq = @SeqDoc

return @Number
end
GO

A 回答 (1件)

提示いただいているソースで現象が発生するのでしょうか?



私も過去に同様の現象に見舞われた記憶があります。
そのときはUPDATEに不正があるのではなくて、
それまでの処理で不正があったことが原因だったような・・

プロシージャの実行はどうやってやられているのでしょうか?
クエリアナライザでプロシージャを呼び出してみたら
なにかしらのエラーが結果として表示されるかも・・

この回答への補足

実行は、VB.NETでADODB.Command
で行っています。

記載したソースは、本来の機能のままですが
現象確認のため
UOTパラメータに文字列を
セットした記述と
UPDATE文だけでも確認できました。

CREATE procedure xml_get_document_seq
@inDate varchar(14),
@outSeq varchar(18) output
as
begin

declare @Number decimal(5)
set @Number = @Number + 1

UPDATE XML_DOCUMENT_SEQ
SET SEQ = @Number

Set @outSeq = '200311202336000001'

return 0
end
GO

何らかのエラートラップを入れてみたほうが
よいのでしょうか?

補足日時:2003/11/20 23:32
    • good
    • 0
この回答へのお礼

少し判明したことがありました
ストアド自体はうまく実行されているようです。

クエリアナライザ上では正常にいきます。

ただ、VB.NETからだとうまくいきません。
ConnectionStringは、

Provider=SQLOLEDB.1
Data Source=サーバー名(サービス名)
Initial Catalog=データベース名
User Id=
Password=

こんな感じです。

お礼日時:2003/11/21 09:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QSQLServerのストアドで戻り値取得したい。

こんにちわ。
いまSQLServer2005でストアドを作成しています。
あるテーブルをSELECTして,あるカラムと件数の両方を出力パラメータに取得したいのですが,
件数は取得できるのですが,カラムが取得できません。
ちなみに下記のようなコードになります。
create procedure funLoginCheck (@UserID char(5), @PassWord varchar(10), @RowCount int output, @DeptID char(2) output)
as select * from MST_Employee
where EmployeeID = @UserID And PassWord = @PassWord; set @deptid = deptid」
deptidを出力パラメータに渡す方法がわかりません。
初歩的なことかもしれませんが,
教えてください。よろしくお願いします。

Aベストアンサー

>deptidを出力パラメータに渡す方法

select @deptid=deptid from MST_Employee
where EmployeeID = @UserID And PassWord = @PassWord

という方法で渡せます。
ところで、この条件でヒットするのは1行だけなのでは?
パラメタ=@RowCountの目的が、よく分かりませんが?
それに今の記述では、@RowCountには何も設定されていません。システムから返される@@ROWCOUNTの内容を、設定したいのでしょうか?

プロシジャとファンクションの定義と実行例を、参考までに示します。

1.プロシジャ
(1)定義
create procedure dbo.funLoginCheck
(@UserID char(5),
@PassWord varchar(10),
@RowCount int output,
@DeptID char(2) output)
as
select @DeptID=deptid
from MST_Employee
where EmployeeID=@UserID
And PassWord=@PassWord
set @RowCount=@@ROWCOUNT

(2)実行
declare @dept char(2)
declare @rowcnt int
exec dbo.funLoginCheck @UserID='U1',@PassWord='P1',
@RowCount=@rowcnt output,@DeptID=@dept output
select @rowcnt,@dept

2.ファンクション
(1)定義
create function dbo.funLoginCheck
(@UserID char(5),
@PassWord varchar(10))
returns char(2)
begin
declare @DeptID char(2)
select @DeptID=deptid
from MST_Employee
where EmployeeID=@UserID
And PassWord=@PassWord
return @DeptID
end

(2)実行
select dbo.funLoginCheck('U2','P2')

>deptidを出力パラメータに渡す方法

select @deptid=deptid from MST_Employee
where EmployeeID = @UserID And PassWord = @PassWord

という方法で渡せます。
ところで、この条件でヒットするのは1行だけなのでは?
パラメタ=@RowCountの目的が、よく分かりませんが?
それに今の記述では、@RowCountには何も設定されていません。システムから返される@@ROWCOUNTの内容を、設定したいのでしょうか?

プロシジャとファンクションの定義と実行例を、参考までに示します。

1.プロシジャ
(1)定義
...続きを読む

QSQLserverのIF文について

どうしてもIF文がうまくいきません
IF文の中にIFを入れ子していますそのIFが複数の条件があります
今までACCESSではELSEIFで条件をいくらでも指定できたのですがSQLの場合はエラーになってしまいます
ご教授おねがいします
------------------------------
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER FUNCTION [dbo].[scfc_part端数処理]
( @PTHASU nvarchar(10), @haken nvarchar(10) )
RETURNS
real
AS
BEGIN
DECLARE @PARTT real
DECLARE @PARTT_H real

if (not(@PTHASU is null))
if @haken='派遣' or @haken='臨時'
if substring(@PTHASU,4,2)>= 50
SET @PARTT = convert(int,LEFT(@PTHASU,2)+1)*60
--ここをいれるとエラー IF substring(@PTHASU,4,2)< 50 and substring(@PTHASU,4,2)>= 20
--ここをいれるとエラー SET @PARTT = convert(int,LEFT(@PTHASU,2)*60 +30
--ここをいれるとエラー if substring(@PTHASU,4,2)< 20
--ここをいれるとエラー SET @PARTT = convert(int,LEFT(@PTHASU,2)*60
ELSE
SET @PARTT = convert(real,LEFT(@PTHASU,2))*60 + convert(real,substring(@PTHASU,4,2))*1

ELSE
SET @PARTT= 0

SET @PARTT_H = convert(real,(floor(@PARTT/60*10000)/10000))

RETURN @PARTT_H

END

どうしてもIF文がうまくいきません
IF文の中にIFを入れ子していますそのIFが複数の条件があります
今までACCESSではELSEIFで条件をいくらでも指定できたのですがSQLの場合はエラーになってしまいます
ご教授おねがいします
------------------------------
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER FUNCTION [dbo].[scfc_part端数処理]
( @PTHASU nvarchar(10), @haken nvarchar(10) )
RETURNS
real
AS
BEGIN
DECLARE @PARTT real
DECLARE @PARTT_H real

if (not(@PTHASU is...続きを読む

Aベストアンサー

マニュアルを読みましょう。

if 条件
真の時の命令文
else
偽の時の命令文

で、真または偽で命令文を2個以上書く場合は、begin~endでブロックを構成する必要があります。

参考URL:http://msdn2.microsoft.com/ja-jp/library/ms182717.aspx

QSQL、ストアドでのUPDATEのアドバイスを下さい。

テーブルA、テーブルBがあってデータ更新の効率的な方法を探しています。


フィールドはそれぞれ、コード、名前、誕生日 があって、

データ、
-----------------------------
A コードなし 名前誕生日
Bコードあり 名前誕生日

でテーブルAに、テーブルBから名前と誕生日で一致するコードを検索
してテーブルAのコードに書き込みたい。

SQL、もしくはストアドプロシジャーで処理したいと思ってます。
処理件数は500前後です。

ストアドを試してみたのですが、コンパイル・エラーが出て上手くいきません。アドバイスをお願いします。

Aベストアンサー

>この場合、TAROの小さい方のコードを拾いたいです。

それでは、

 update a set
 code = (select min(b.code)
 from b
 where a.name = b.name
 and a.birth = b.birth)

これでどうでしょうか?

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

QSELECT INTOで一度に複数の変数へ代入をするにはどのようにすれがよいでしょうか?

初めてこちらで質問させていただきます。
どうぞよろしくお願いします。
早速ですが、
現在ストアドファンクション(PL/pgSQL)にて以下のような形になっています。
変数d1,d2,d3に値をセットするにあたり
テーブルt1を3回スキャンしています。
これを1回のスキャンでセットするような
方法はないのでしょうか?

DECLARE
d1 integer;
d2 integer;
d3 varchar(10);

begin
select min(c1) into d1 from t1;
select min(c2) into d2 from t1;
select min(c3) into d3 from t1;
各種処理
return v;
end;

気持ち的には以下のようなSQLを書きたいのですが、
syntax error となります。
(NG例)
select min(c1) into d1,min(c2) into d2,min(c3) into d3 from t1;

何か良い案がありましたら教えてください。
「それは出来ません」と言う回答でもありがたいです。
※あきらめがつくので。。

それではよろしくお願いします。

初めてこちらで質問させていただきます。
どうぞよろしくお願いします。
早速ですが、
現在ストアドファンクション(PL/pgSQL)にて以下のような形になっています。
変数d1,d2,d3に値をセットするにあたり
テーブルt1を3回スキャンしています。
これを1回のスキャンでセットするような
方法はないのでしょうか?

DECLARE
d1 integer;
d2 integer;
d3 varchar(10);

begin
select min(c1) into d1 from t1;
select min(c2) into d2 from t1;
select min(c3) into ...続きを読む

Aベストアンサー

select min(c1),min(c2),min(c3) into d1,d2,d3 from t1;
でダメ?

Q更新ロックとデッドロック

データベースを勉強中の者です。ロックの種類についてどなたかご教示いただけますでしょうか。

ロックの種類は、次の三種類ですよね。

・共有ロック
・排他ロック
・更新ロック

共有ロックの意味は理解できていると思うのですが、更新ロックがよくわかりません。
更新ロックにすると次のように動作するそうですね。

1.更新を前提にして共有ロックをかける。
2.更新する前に排他ロックに切り替わる。

排他ロックも更新時に使うロックですが、排他ロックと更新ロックの違いというか、使い分けがよくわかりません。
データを更新するためには排他ロックをかけないといけないのはわかりますが、その前に共有ロックをかける意味は?

http://f29.aaa.livedoor.jp/~snaka/PukiWiki/PukiWiki.php?SQLServer%2F%A5%ED%A5%C3%A5%AF#na5d5d64

上のサイトを読んで「デッドロックを回避するため」といったんは理解したのですが、上司は「更新ロックとデッドロックは関係ない」と言います。

私の解釈が間違っているのでしょうか。それとも上司?

データベースを勉強中の者です。ロックの種類についてどなたかご教示いただけますでしょうか。

ロックの種類は、次の三種類ですよね。

・共有ロック
・排他ロック
・更新ロック

共有ロックの意味は理解できていると思うのですが、更新ロックがよくわかりません。
更新ロックにすると次のように動作するそうですね。

1.更新を前提にして共有ロックをかける。
2.更新する前に排他ロックに切り替わる。

排他ロックも更新時に使うロックですが、排他ロックと更新ロックの違いというか、使い分けがよくわかり...続きを読む

Aベストアンサー

sqlcmdのプロンプトを二つ立ち上げて
(トランザクション1)
begin tran
go
select * from テーブル with ( updlock ) where 条件
go

(トランザクション2)
update テーブル set 項目 = ~ where 条件
go

として見てください。トランザクション2は待ちになります。
トランザクション1のselect文の with ( updlock ) を取ると待ちになりません。

Qストアドプロシージャ_カーソルのヒット件数

いつもお世話になっています。
SQLServer7.0です。

ストアドプロシージャでカーソルを使用し、オープンしたカーソルの件数を調べたいのですがうまくいきません。

Declare curs2 cursor for
Select [項目名]
From [テーブル名]
Where [検索条件]

Open curs2
Print @@CURSOR_ROWS

この「@@CURSOR_ROWS」変数でヒット件数を取得できるように参考書では書いてあるのですが、実際Printしてみると、カーソルをオープンする前だと 0 で、オープンした後だと-1 です。

特にエラーだとか、対象データがないというわけではありません。実際その後ヒットした件数分行う処理は正常に出来ています。

ただ、どうしても処理を行う前に件数を知りたいのです。カーソルの変数だけでは取れないとなると セレクトしたカーソルと全く同じセレクトを実行して@@ROWCOUTで取るしかないかなって思ってるのですが・・・。どうも建設的ではないなって思ってます。

カーソルの件数を取得するにはどうしたらよいのでしょうか?

いつもお世話になっています。
SQLServer7.0です。

ストアドプロシージャでカーソルを使用し、オープンしたカーソルの件数を調べたいのですがうまくいきません。

Declare curs2 cursor for
Select [項目名]
From [テーブル名]
Where [検索条件]

Open curs2
Print @@CURSOR_ROWS

この「@@CURSOR_ROWS」変数でヒット件数を取得できるように参考書では書いてあるのですが、実際Printしてみると、カーソルをオープンする前だと 0 で、オープンした後だと-1 です。

特にエラーだと...続きを読む

Aベストアンサー

一回
Select count([項目名])
From [テーブル名]
Where [検索条件]

とやって、数を取り出してから カーソルのほうを
やったらどうでしょうか?


あと
参考URLでは
SELECT @@CURSOR_ROWS
で取得しているみたいですが・・・。

参考にならなかったら失礼。

参考URL:http://www.horikawa.ne.jp/msde/gihyo/sql07/sql07_07.html

Q一つのトランザクションでSELECTとUPDATEできますか? (ADO.NET)

いつもお世話になっております。

ADO.NETの話なのですが、トランザクションを開始したコネクションオブジェクトで
DataAdapterを使ったSELECTと、ExecuteNonQueryを使ったUPDATEを交互に繰り返し
行うことはできるでしょうか?

現状できていないので可能なのであれば共通関数の見直しが必要かと思っています。
いまはSELECTとUPDATEを別のコネクションで行っているのですが、UPDATE後に
同じテーブルの該当レコードをSELECTにいくため、デッドロックが発生しています。

Aベストアンサー

>それにしてもコネクションとトランザクションオブジェクトを別々に
>渡してやる必要性がよく理解できません。コネクションオブジェクトから
>トランザクションオブジェクトも参照できるのでは?と思うのですが・・・。

たしかに私も腑に落ちない・・・気がします
なにか別に設定が必要な理由があるのかも知れませんね
複数のトランザクションが存在する場合に指定が必要になるのかも!

私の過去のコードにはしっかり
sqlCommand.Transaction = tran
がありました(いつの間にか記述してたみたい)
すいません。#2ではまったくその事に触れていませんでした

憶測での回答になってしまいますが
トランザクションが割り当てられたコマンドが実行されたときに
自動的にBegin Tranされ
トランザクションが割り当てられていないコマンドが実行されたときに
自動的にCommit Tranが実行されてしまうのかも知れません
時間があったら実証して見たいと思います

QUPDATE文のWHERE条件に他のテーブルのフィールドも入れたい

SQL文についてです。

表Aで列1と列2が'◎'のものについて、列3,列4,列5をそれぞれ'○','△','×'に更新したい場合は下記でOKだと思います。
UPDATE 表A
SET 列3 = '○', 列4 = '△', 列5 = '×'
WHERE 列1 = '◎' AND 列2 = '◎'

列1と列2をキーとして表Aと結合できる表Bが存在するとします。
条件に表Bの列6が'□'だった場合を追加したい時、どのような方法で行えば良いのでしょうか?
内部結合やWHERE EXISTSなどをいろいろ調べたのですが、SQL文に慣れていないためかうまくいきません。
初歩的な質問で申し訳ありませんが過去質問で参考になるものがなかったのでお願いします。

Aベストアンサー

UPDATE 表A
SET 列3 = '○', 列4 = '△', 列5 = '×'
WHERE 列1 = '◎' AND 列2 = '◎'
AND EXISTS
( SELECT 1 FROM 表B
WHERE 表B.列1 = 表A.列1
AND 表B.列2 = 表A.列2
AND 表B.列6 = '□' )
じゃだめですか。

QCloseとDisposeの違い

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、タイマーコントロールのイベントに記述していますと、それは実行され続けます。

これを防ぐために、Me.Dispose() を使います。すると、きれいにプロセスは終了し、イベントは発生しない模様です。

そこで、「フォームを閉じる」意味のMe.Close() をすべてMe.Dispose() に変えてしまいました。確実にプロセスを破棄出来ると思ったからです。Webで調べると、違いは「再利用できる、できないの違い」という答えがありましたが、それはきっと、ファイルやオブジェクトのことで、フォームの場合は、再びShowまたはShowDialogで表示させることは可能でしたので、特に問題は感じていませんでした。

ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。Me.Close() に変えるとうまくいきました。

わけわからなくなってきました。。。

ちなみに、その残ったフォームは、スタートアップフォームであり、別のフォームからShowまたはShowDialogメソッドで呼び出したものではありません。

ここで4つの仮説を立ててみました。

1. ShowDialogで呼び出したフォームは、Me.Dispose()、Showで呼び出した、あるいは、スタートアップフォームは、Me.Close() すれば破棄できる

2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

3. 呼び出し方ではなく、別の要因が存在する

4. 併記する必要がある場合がある

Me.Close()
Me.Dispose()

または、

Me.Dispose()
Me.Close()



どれが正しいのでしょうか?どなたがご存じの方がいらっしゃいましたら、ご教授いただけませんでしょうか? どうぞよろしくお願い申し上げます。ありがとうございました。

みなさまこんばんわです。よろしくお願い申し上げます。

VB.NET 2008でコーディングしています。
CloseとDisposeの違いについて教えていただきたいのです。

これらのメソッドは、開いたファイルを閉じるときなどにも使いますが、今回お尋ねするのは、フォームを閉じるとき、しかも、自ら呼び出すとき(Me.Close() と、Me.Dispose() )のみに限ったこととしてお話しさせていただきます。

たとえば、ShowDialog() で呼び出したフォームは、そのフォーム内でMe.Close() しても、プロセスは残り、たとえば、...続きを読む

Aベストアンサー

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリケーション設定で、「最後のフォームを閉じるとき」にアプリケーションがシャットダウンする設定になってるのに、シャットダウンしてくれないことが起こりました。調べてみると、Me.Dispose() が原因。
Me.Close() に変えるとうまくいきました。

通常はどちらでもうまくいきます。

>2. ShowDialogで呼び出したフォームは、Me.Dispose()、スタートアップフォームは、Me.Close()、Showで呼び出したフォームは、どちらでも、破棄できる

ShowDialogの場合は、メソッド内部で、ハンドルが破棄されているため、Close()メソッドの際にDispose()メソッドが呼び出されます。

>3. 呼び出し方ではなく、別の要因が存在する

そう思います。

>4. 併記する必要がある場合がある

インスタンスを明示的に破棄したほうがよい場合は多く存在します。
Disposeが使えるメンバはIDisposableをインターフェースとして持っているメンバです。
これらのメンバは、外部とのやり取りを行うものが多くあります。
たとえばSQLClientに含まれるようなメンバです。

外部とのコネクションを確実に破棄を保障してほしいなどという場合がありますよね、このようなときに使用します。

Using構文を使用するのとまったく同じ理由になります。
正確にはUsing構文を使用できるメンバには条件があります、IDisposableをインターフェースとして持っているメンバに限るというものです。

ほかにもガーベージコレクタによるファイナライズを伴うかどうかという違いがあります。
Disposeの場合はファイナライズが同時に行われるため、使用していたメモリ空間を開放することができます。

上記のような理由により、
Me.Close()
Me.Dispose()
は両方書いたほうがよいと思います。

蛇足ですが、
Me.Dispose()
Me.Close()
はエラーになります。
Me.Dispose()により、Me本体(インスタンス)は削除されてしまいます。
存在しないMeに対してCloseメソッドを要求することはできないためです。

Me.Close()
Me.Dispose()
は根本的に違うものです。

formについて、Close()メソッドはフォームの表示を終了させるメソッドです。

ほかのクラスも同様。すべてのDispose()メソッドについて、これはインスタンスの破棄を明示的に行うものです。

>再利用できる、できないの違い

Dispose()はインスタンスが破棄されるため、再びコンストラクタを用いて、インスタンスを生成しないいけません。

一方Close()はインスタンスが残っているので、それを利用することができます。

>1. ところが、アプリ...続きを読む


人気Q&Aランキング