質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

1回答

3343閲覧

SQL Serverでプログラム中のDictionaryを使用して、SQL文でUPDATE ~ SELECTしたい

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2021/07/09 06:29

編集2021/07/09 08:07

SQL Serverでプログラム中のDictionaryを使用して、SQL文でUPDATE ~ SELECTしたいです。

利用環境 SQL Server 2019 Express

1つのSQLコマンドで下記の①②③を実行するようなイメージです。
① 仮テーブル作成
② @tempにプログラム中のDictionaryを追加したい { { 1: 1}, { 2: 2} } … @tempのIdとOrderに該当
③ @tempの情報でUPDATE ~ SELECT

どなたかご教授をお願いします。

SQL

1 /* ① */ 2DECLARE @temp TABLE ( 3 [Id] int NOT NULL, 4 [Order] int NOT NULL 5) 6 7 /* ② やりかたがわかっていない。Insertするだけ? */ 8 9 10 /* ③ 下記の例はエラーするかも */ 11UPDATE [dbo].[M_Tests] 12SET [Order] = B.[Order] 13FROM [dbo].[M_Tests] AS A 14 LEFT OUTER JOIN ( 15 SELECT [Id], ROW_NUMBER() OVER ( 16 ORDER BY [Order] ASC 17 ) AS 'Order' 18 FROM @temp 19) AS B 20ON A.[Id] = B.[Id]

C#

1public async Task<int> SortAsync(IReadOnlyDictionary<long, long> dictionaries) { 2 string sql = @"SQL文をここに書く" 3 4 await this._context.Database.ExecuteSqlRawAsync(sql, null); // ← キーとかなら第2引数以降にわたせる 5 6 return; 7}

追記

DataTableのみ作成してみました。

C#

1// DataTableのみ作成してみました。 2DataTable dataTable = new DataTable("temp"); 3dataTable.Columns.Add("id", typeof(long)); 4dataTable.Columns.Add("order", typeof(long)); 5 6foreach (var dictionary in dictionaries) { 7 DataRow dataRow = dataTable.NewRow(); 8 dataRow["id"] = dictionary.Key; 9 dataRow["order"] = dictionary.Value; 10}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

1つのSQLコマンドで下記の①②③を実行するようなイメージです。

SQLのコマンド自体が分かれているので不可能です。
ExecuteSqlRawAsyncに渡すパラメータとしてのSQLがセンテンス(;)で区切られて実行可能なら同じようにSQLを記述すれば良いだけだと思います。

若しくは、①②③をセットにしたストアドを作成し、それを呼び出すとか。

投稿2021/07/09 07:37

sazi

総合スコア25327

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/07/09 07:44 編集

コメントありがとうございます。 1つのSQL文というのは間違いでした。 言われているとおり;で区切れば問題ないようです。 調べてみたところ INSERT で追加できるようですが、INSERTがボトルネックなので INSERTにDataTableを使う方法があるみたいです。 EntityFrameWorkでsqlParamaterを使うみたいではありますが。
sazi

2021/07/09 07:52 編集

「プログラム中のDictionaryの内容をM_Testsに更新した上で結果を取得したい」という事でしょうか? であるなら、 1.プログラム中のDictionaryの内容をM_Testsに更新 2.M_Testsの内容を取得 に分けて考えて、2は特に問題ないでしょうから、1の実装について考えれば良いと思います。
退会済みユーザー

退会済みユーザー

2021/07/09 08:06 編集

1の実装についてSqlParameterが使えないか考えています。 SqlParameterでDataTableを使えると、一時テーブルを作成する手間がなく、そのままテーブルとして利用できるようです。 EFでSqlParameterが使えるのかはわかっていなく調べているところですが var param = new SqlParameter("@Temp", dataTable) { TypeName = "dbo.Temp", SqlDbType = SqlDbType.Structured }; await this._context.Database.ExecuteSqlRawAsync(sql, param); await this._context.Database.ExecuteSqlRawAsync(sql, param); の paramが {1}として取り出せるはずですが、この行でエラーが出ています。
sazi

2021/07/09 08:16 編集

> SqlParameterでDataTableを使えると 単に配列のパラメータとして渡されるだけでは無いのでしょうか? また、その後のUPDATE文でどのように利用するつもりですか? @Tempにinsert into values()で追加でも良いのでは?
退会済みユーザー

退会済みユーザー

2021/07/09 08:23

単に配列のパラメーターとしてわたしたいです。 それをUPDATE ~ SELECTのテーブルとして使用したいです。 @Tempにinsert into values()で追加でも良いとは思っています。
sazi

2021/07/09 08:36

> UPDATE ~ SELECTのテーブルとして使用したいです。 配列のパラメータで受け取るとupdateが面倒だと思うので、@tempにinsertした方が良いかと思います。
退会済みユーザー

退会済みユーザー

2021/07/09 09:21 編集

@tempにinsertする方法で、プログラムでSQL文を作成して解決できました。 ありがとうございました。 生のSQL文の方は下記のようにしました。 DECLARE @temp TABLE ( [Id] int NOT NULL, [Order] int NOT NULL) INSERT INTO @temp ([Id], [Order]) VALUES (1, 3) INSERT INTO @temp ([Id], [Order]) VALUES (2, 1) INSERT INTO @temp ([Id], [Order]) VALUES (3, 2) UPDATE [Test].[dbo].[M_Tests] SET [Order] = B.[Order] FROM [Test].[dbo].[M_Tests] AS A LEFT OUTER JOIN ( SELECT [Id], ROW_NUMBER() OVER ( ORDER BY [Order] ASC ) AS 'Order' FROM @temp AS B ) AS B ON A.[Id] = B.[Id] WHERE A.[Id] = 1 OR A.[Id] = 2 OR A.[Id] = 3 // ←テストのため3件にしぼってます。 Updateをかける時にIdが存在するかはチェックをかけないとエラーするのでそれは追加したほうがよいかもしれません。 ※全件あることは前提ですが。 ※DataTableを使おうとしていた時、ソースがきたなくなってしまったのもありますが、 シンプルに一時テーブルに追加したほうがわかりやすいし、レスポンスのネックもあまり感じませんでした。
退会済みユーザー

退会済みユーザー

2021/07/09 10:18

WHEREでNULLチェックをして対応しました。 DECLARE @temp TABLE ( [Id] int NOT NULL, [Order] int NOT NULL) INSERT INTO @temp ([Id], [Order]) VALUES (1, 3) INSERT INTO @temp ([Id], [Order]) VALUES (2, 1) INSERT INTO @temp ([Id], [Order]) VALUES (3, 2) UPDATE [Test].[dbo].[M_Tests] SET [Order] = B.[Order] FROM [Test].[dbo].[M_Tests] AS A LEFT OUTER JOIN ( SELECT [Id], ROW_NUMBER() OVER ( ORDER BY [Order] ASC ) AS 'Order' FROM @temp AS B ) AS B ON A.[Id] = B.[Id] WHERE B.[Id] IS NOT NULL
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問