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

このQ&Aのポイント
  • ストアドファンクション(PL/pgSQL)において、テーブルt1を3回スキャンして変数d1、d2、d3に値をセットする方法についての質問です。1回のスキャンでセットする方法はあるのか、良い案があれば教えてください。
  • 現在のコードでは、select文を3回使用してテーブルt1から最小値を取得し、変数d1、d2、d3に代入しています。しかし、1回のスキャンでセットする方法を探しています。
  • 要件としては、select文を1回のスキャンで実行し、変数d1、d2、d3に値を代入する方法が求められています。良い案があれば教えてください。
回答を見る
  • ベストアンサー

SELECT 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; 何か良い案がありましたら教えてください。 「それは出来ません」と言う回答でもありがたいです。 ※あきらめがつくので。。 それではよろしくお願いします。

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

  • ベストアンサー
  • nora1962
  • ベストアンサー率60% (431/717)
回答No.2

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

baunce
質問者

お礼

ありがとうございました。 うまくいきました。 nora1962さんの構文を見てすぐ 「なるほど!」と思い 試してみた結果うまくいきました。 本当にありがとうござおました。 最後に返事が遅れてしまい申し訳ありませんでした。

その他の回答 (2)

回答No.3

select intoまで辿り着いているのだから、簡単に調べられると思うのですが。。。 select 式1,式2,式3 into 変数1,変数2,変数3 from 表名 のように、式と対応する変数を複数書きます。 なお、PostgreSQLでは、8.0前後くらいで構文に変更(into句の位置)があったと思います。質問にある使い方は、変更後の使い方です。

baunce
質問者

お礼

chukenkenkouさん ありがとうございました。 おかげさまで解決しました。 確かにご指摘の通りですね。 ただ自分なりには調べて見たのですが、 マニュアル等ではこの方法を読み取れませんでした。 すみませんでした。 ご丁寧な解説感謝します。

  • Splatter
  • ベストアンサー率41% (181/440)
回答No.1

カーソルを使用することはもう検討されましたか? http://www.bnote.net/mysql/appendix/cursors.shtml

baunce
質問者

お礼

すばやいアドバイスありがとうございます。 はい。カーソルを使えばできるだろうな。とは感じておりました。 できれば「カーソルを使わない方法」があれば教えてください。 最初の質問でこの事を記載すべきでした。 すみません。

関連するQ&A

  • pl/pgsqlで変数の扱い

    pl/pgsqlで変数が文字列として扱われてしまうのですがどうすればいいのでしょうか。 具体的には以下のような感じです。 CREATE OR REPLACE FUNCTION test_func() RETURNS VOID AS $$ DECLARE test_val TEXT ; ofs_num INTEGER := 0; lmt_num INTEGER := 0; t_name TEXT := 'schema1.table1'; BEGIN SELECT INTO ret_val * FROM t_name OFFSET ofs_num LIMIT lmt_num; END; $$ LANGUAGE plpgsql; 上記のofs_numやlmt_numは変数として認識してくれるのですが FROMに続く「t_name」が変数ではなくそのままの文字列として認識されてしまいます。 t_nameを変数として認識させる方法はありませんでしょうか。 教えていただけると助かりますm(_)m

  • select into句のトランザクションについて

    お世話になってます。 sqlについて質問です。 ddlを発行するとトランザクションは暗黙的にコミットされると思いますが、 select into #temptable ・・・ のように、select into 句で一時テーブルを作成した場合、トランザクションはどうなるのでしょうか? また、以下のように一時テーブルと普通のテーブルで挙動は変わりますか? begin transaction select into #temptable from A ← ここでコミットされてしまう? …(1) select into temptable from A ← ここでコミットされてしまう? …(2) rollback transaction 以上、よろしくお願いいたします。

  • バインド変数について

    PL/SQLのバインド変数について調べていますが理解できず困っています。 [理解内容] 1.利点  :SQL文の検索にバインド変数を利用すると、同一のSQLとして実行できる   ⇒ 繰り返し処理(ループ)では有効 2.使用方法  :静的SQL・動的SQLで使用可能   [疑問点]   静的SQLではバインド変数をどう宣言すればよいですか?   [SQL*Plus]・[動的SQL]は例文がありました   ●SQL*Plusでの宣言方法    (例)     SQL> set null '<null>'     SQL> set head off     SQL> variable var_at_sqlplus number   ●動的SQLの記述方法    (例)     declare      v_sql varchar2(256);      v_id varchar2(3);     begin      v_sql = 'select id into :v_id from test';      execute immediate v_sql into v_id;     end;   ●静的SQL ・・・【 エラーになる 】     declare      variable v_id varchar2(3);     begin      select id into :v_id from test'     end; どんな事でもかまいませんので回答よろしくお願いします

  • Mysql ストアドファンクション 意図しない結果

    以下の通りストアドファンクションを作成しました。 関数名:fgetLineNew インパラメータ:shop Varchar 8 ※1つだけ。。。 戻り値: Int 11 <ソース> BEGIN DECLARE pline INTEGER(11) DEFAULT NULL; SELECT COUNT(1) INTO pline FROM `hoge` WHERE `SHOP` = shop; IF pline IS NULL THEN SET pline = 10000; END IF; RETURN pline; END 上記のように、作成したストアドファンクションですが、 どんな引数を入れても、戻り値が全ての行(817行)になってしまいます。 以下を参照。 Where区がまったく働いていないのですが、何が原因なのでしょうか。 教えてください。 <ストアドファンクション実行> mysql> select fgetLineNew(1); +----------------+ | fgetLineNew(1) | +----------------+ | 817 | +----------------+ 1 row in set (0.01 sec) mysql> select fgetLineNew(525); +------------------+ | fgetLineNew(525) | +------------------+ | 817 | +------------------+ 1 row in set (0.01 sec) mysql> select fgetLineNew(101); +------------------+ | fgetLineNew(101) | +------------------+ | 817 | +------------------+ 1 row in set (0.00 sec) mysql> select fgetLineNew(525); +------------------+ | fgetLineNew(525) | +------------------+ | 817 | +------------------+ 1 row in set (0.00 sec) mysql> select fgetLineNew('525'); +--------------------+ | fgetLineNew('525') | +--------------------+ | 817 | +--------------------+ 1 row in set (0.01 sec)

    • ベストアンサー
    • MySQL
  • ストアドでのwhile文の利用法

    SQLServerでのストアドについてはこちらでうかがってもよろしいのでしょうか? ストアド内にてwhileでのループ文作成についてなんですが、 以下のようなストアドでSELECT内でA.NO1....とあるとおもうのですが、 これを@numRankの数だけ、A.NO(フィールド)を増やしたいのですが、 ここからどのようにつくればよろしいのでしょうか? CREATE PROCEDURE usp_Enquete @ask_idvarchar(10) AS DECLARE @strvarchar(1000) DECLARE @numRankint DECLARE @Counterint BEGIN SELECT @numRank = count(*) FROM B_Answer WHERE ask_id = @ask_id END SET NOCOUNT ON SET @Counter = 1 WHILE @Counter <= @numRank BEGIN SET @str = ' SELECT count(ansList.NO1) AS NumAns, A.NO1, A.NO2, A.NO3 FROM ・ ・ ・

  • 異なるデータベースでのSELECT INTO

    昨日と同じところでつまずいているのですが、 みなさまご助言お願いいたします。 タイトルのようにSELECT INTO構文を 2種類のデータベースにまたがって使用したいと思っています。 Dim adoConA As ADODB.Connection 'データベースA Dim adoConB As ADODB.Connection 'データベースB Dim rs As ADODB.Recordset Dim sSQL As String sSQL = "SELECT * FROM 顧客情報" ' データベースAからテーブル取得 rs.Open sSQL, adoConA ' 取得したテーブルをデータベースBに新しいテーブルとして保存 ????? 実際には、SELECT INTOは無理かなと思い、 上記のように、一度レコードセットに取得して それをテーブルBに保存すると言う方法を行おうと 思っているのですが、やり方がわかりません。 もちろん、別の方法でも可能ならば 別の方法でも構いませんので、 おわかりになるのであれば教えてください。

  • PL/pgSQLの返り値の取得方法について

    now()の結果を返すだけの以下の2つのPL/pgSQLを試しに作りました。SQL1は正しく結果が返ってきますが、SQL2は結果が何も返ってきません。どなたか説明できる方、いらっしゃいますでしょうか。宜しくお願い致します。 ■SQL1 CREATE OR REPLACE FUNCTION select_now1() RETURNS date AS $$ DECLARE d_current DATE := NULL; BEGIN SELECT INTO d_current now(); RETURN d_current; END; $$ LANGUAGE PLpgSQL; ■結果1 select_now1 ------------- 2011-03-19 (1 行) ■SQL2 CREATE OR REPLACE FUNCTION select_now2(OUT d_current date) AS $$ DECLARE d_current DATE := NULL; BEGIN SELECT INTO d_current now(); END; $$ LANGUAGE PLpgSQL; ■結果2 select_now2 ------------- (1 行)

  • 変数の取り扱いについて

    はじめまして。思いっきりSQLSERVERは初心者なんですが宜しくお願いします。 現在SQLSERVER2005です。 ややこしくなるので要点だけ以下まとめています。 変数を利用してレコードを抽出する時なんですが… ALTER PROCEDURE Test @Rank INT BEGIN DECLARE @SELECT AS VARCHAR(100) DECLARE @WHERE AS VARCHAR(100) DECLARE @SQL AS VARCHAR(200) SET @SELECT = 'SELECT * FROM tblA ' SET @WHERE = 'WHERE Rank > ' + @Rank SET @SQL = @SELECT + @WHERE EXEC(@SQL) END 実行すると varchar の値 'WHERE Rank > 'をデータ型 int に変換できませんでした。 となります。 Rank部分が数値なんですが、どのように取扱いすべきなんでしょうか。

  • SELECT文の結果をDEFINEの値として使用したいのですが。。。 [Oracle9i]

    こんにちは。 test.sqlでバインド変数として使用されている"hensu"に対して、SELECT文の結果を代入したいと考えています。 そこで、DEFINEで下記のようにセットしてみようとしたのですが、"hensu"には"hensu_id"という文字として入ってしまうようです。 DECLARE hensu_id number ; BEGIN select min(id) into hensu_id; END; / DEFINE hensu =hensu_id @c:\test.sql 初歩的な質問ですみませんが、宜しくお願いします。

  • TranzactSQL文 文字列変数同士の連結

    文字列変数の連結について質問いたします。 通常以下の場合、結果は望んだとおりになります。 ----------------------------------------------- SET @会社=N'A社' SET @別会社=N'B社' SET @結果=@会社+'、"+@別会社 SELECT @結果 ’A社、B社' ---------------------------------------------- 以下のように記述にして,複数会社名を連結させる目的で FETCHを使用して変数に値を格納しようとしていますが 結果NULLが返されるのはなぜでしょうか。 ---------------------------------------------- DECLARE myCursor CURSOR FOR SELECT 会社名 FROM 会社マスター OPEN myCursor FETCH NEXT FROM myCursor INTO @会社名 WHILE @@FETCH_STATUS=0 BEGIN     @結果=@結果+@会社名    FETCH NEXT FROM myCursor    INTO @会社名 END CLOSE myCursor DEALLOCATE myCursor SELECT @結果