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

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

新規登録して質問してみよう
ただいま回答率
85.34%
.NET

.NETとは、主に.NET Frameworkと呼ばれるアプリケーションまたは開発環境を指します。CLR(共通言語ランタイム)を搭載し、入力された言語をCIL(共通中間言語)に変換・実行することが可能です。そのため、C#やPythonなど複数の言語を用いることができます。

VBScript

VBScript(Visual Basic Scripting Edition)はMicrosftが開発したスクリプト言語であり、Visual Basicのサブセットです。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

1回答

123閲覧

VB.NETのバインド変数を使用したSQLのエラーハンドリングについて

MORO

総合スコア1

.NET

.NETとは、主に.NET Frameworkと呼ばれるアプリケーションまたは開発環境を指します。CLR(共通言語ランタイム)を搭載し、入力された言語をCIL(共通中間言語)に変換・実行することが可能です。そのため、C#やPythonなど複数の言語を用いることができます。

VBScript

VBScript(Visual Basic Scripting Edition)はMicrosftが開発したスクリプト言語であり、Visual Basicのサブセットです。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2025/01/10 16:49

実現したいこと

sqlのバインド変数設定後にExcuteQueryを使用し、SQLの実行とエラーハンドリングを実施したい
※ExcuteQueryはソースコードDB関連処理を参照ください
※WEBアプリのログイン機能を実装しています。

環境:Windows 11 Home
IDE:VisualStudio 2022
DB:Oracle19c
言語:VB.NET

発生している問題・分からないこと

〇ソースコード(バインド処理)内
→SQLインジェクション対策で以下のバインド処理を実施

cmd.Parameters.Add(New OracleParameter(":loginID", loginId))
cmd.Parameters.Add(New OracleParameter(":password", password))

上記方法でバインド変数を設定した場合、ExecuteScalarを使用して実行する制限があるため
用意していた実行関数が使用できず、エラーハンドリングが実施できない。

単純にSQL内にのバインド箇所に変数の値を設定すれば解決する話ではあるのですが、
SQLインジェクションの観点でバインドすべきという記事を見たので
どのようにSQLを実行し、エラーハンドリングを実施すべきか悩んでいます。

プログラミング経験が浅いためお力添えいただけないでしょうか。

該当のソースコード

DB関連処理

1Imports System.Data.Common 2Imports System.IO 3Imports Oracle.ManagedDataAccess.Client 4 5Public Class DataAccess 6 Implements IDisposable 7 8 Private conn As DbConnection = Nothing 9 Private factory As DbProviderFactory = Nothing 10 Private tran As DbTransaction = Nothing 11 Private isDisposed As Boolean = False 12 13 ' Connectionプロパティを追加 14 Public ReadOnly Property Connection As DbConnection 15 Get 16 Return conn 17 End Get 18 End Property 19 20 Public Sub New() 21 Dim dcsb As DbConnectionStringBuilder 22 23 Try 24 factory = DbProviderFactories.GetFactory("Oracle.ManagedDataAccess.Client") 25 dcsb = factory.CreateConnectionStringBuilder 26 dcsb("Data Source") = ConfigurationManager.AppSettings("dataSource") 27 dcsb("User ID") = ConfigurationManager.AppSettings("userId") 28 dcsb("Password") = ConfigurationManager.AppSettings("pass") 29 30 conn = factory.CreateConnection() 31 conn.ConnectionString = dcsb.ConnectionString 32 33 conn.Open() 34 conn = CType(conn, OracleConnection) 35 tran = conn.BeginTransaction() 36 37 Catch ex As Exception 38 LogError(ex.Message) 39 Rollback() 40 41 End Try 42 43 End Sub 44 45 Public Function ExcuteQuery(ByVal SQLContents As String) As DataSet 46 47 Dim cmd As DbCommand 48 Dim da As DbDataAdapter 49 Dim ds As New DataSet 50 51 Try 52 cmd = conn.CreateCommand 53 cmd.CommandText = SQLContents 54 55 da = factory.CreateDataAdapter() 56 da.SelectCommand = cmd 57 da.Fill(ds) 58 59 Catch ex As Exception 60 LogError(ex.Message) 61 62 End Try 63 64 Return ds 65 66 End Function 67 68 Public Function ExecuteNonQuery(ByVal SQLContents As String, Optional ByVal isCommit As Boolean = True) As Integer 69 70 Dim cmd As DbCommand 71 Dim affectedRows As Integer = 0 72 73 Try 74 cmd = conn.CreateCommand 75 cmd.CommandType = CommandType.Text 76 cmd.CommandText = SQLContents 77 78 affectedRows = cmd.ExecuteNonQuery() 79 If isCommit Then 80 Commit() 81 End If 82 83 Catch ex As Exception 84 LogError(ex.Message) 85 Rollback() 86 87 End Try 88 89 Return affectedRows 90 91 End Function 92 93 Public Sub Commit() 94 Try 95 tran.Commit() 96 tran = conn.BeginTransaction() 97 Catch ex As Exception 98 End Try 99 End Sub 100 101 Public Sub Rollback() 102 Try 103 tran.Rollback() 104 tran = conn.BeginTransaction() 105 Catch ex As Exception 106 End Try 107 End Sub 108 109 ' IDisposable の実装 110 Public Sub Dispose() Implements IDisposable.Dispose 111 Dispose(True) 112 GC.SuppressFinalize(Me) 113 End Sub 114 115 Protected Overridable Sub Dispose(disposing As Boolean) 116 If Not isDisposed Then 117 If disposing Then 118 ' マネージリソースの解放 119 If tran IsNot Nothing Then 120 tran.Dispose() 121 tran = Nothing 122 End If 123 If conn IsNot Nothing Then 124 conn.Dispose() 125 conn = Nothing 126 End If 127 End If 128 ' アンマネージリソースの解放が必要ならここで処理 129 isDisposed = True 130 End If 131 End Sub 132 133 Public Sub LogError(errorMessage As String) 134 Dim logFolder As String = "C:\Logs" 135 Dim logFile As String = Path.Combine(logFolder, "error_log.txt") 136 Dim logMessage As String = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} - {errorMessage}" 137 138 Using writer As New StreamWriter(logFile, True) 139 writer.WriteLine(logMessage) 140 End Using 141 End Sub 142 143End Class
Imports Oracle.ManagedDataAccess.Client Public Class Login Inherits System.Web.UI.Page Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load End Sub Protected Sub LoginButtonClick(sender As Object, e As EventArgs) Dim loginId = txtLoginID.Text Dim password = txtPassword.Text Dim sqlQuery As String = GetLoginUser() Using dataAccess As New DataAccess() Using conn As OracleConnection = dataAccess.Connection Using cmd As New OracleCommand(sqlQuery, conn) cmd.Parameters.Add(New OracleParameter(":loginID", loginId)) cmd.Parameters.Add(New OracleParameter(":password", password)) Dim result As Integer = Convert.ToInt32(cmd.ExecuteScalar()) If result > 0 Then Response.Redirect("main.aspx") Else lblMessage.Text = "ログインIDまたはパスワードが間違っています。" End If End Using End Using End Using End Sub End Class
Module Queries ' 複数行のSQL文を返す関数 Public Function GetLoginUser() As String Dim sql As String = " SELECT count(ID) FROM ユーザー WHERE ID = :loginID AND パスワード = :password " Return sql End Function End Module

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

〇試したこと
実行時のソースコードとIF文の条件をいかに変更しましたが、countが0となりエラーになります。

Dim ds As DataSet = dataAccess.ExcuteQuery(sqlQuery)
If ds.Tables.Count > 0 Then

〇調べたこと
バインド変数後のsql文の取得
→取得できないという記事しか見つけることができませんでした。

補足

特になし

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

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

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

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

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

guest

回答1

0

ベストアンサー

バインド変数後のsql文の取得
→取得できないという記事しか見つけることができませんでした。

はい、本質的に不可能です。データベースサーバでバインドが実装されている場合、プログラムからは「値の抜けたSQL文」と「値」が別々に送られます。

用意していた実行関数が使用できず、エラーハンドリングが実施できない。

こちらの関数について「値の抜けたSQL文」と「値」の両方を引数で受け取るようにする、というのが最適解ではないでしょうか。

投稿2025/01/10 17:43

maisumakun

総合スコア146175

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

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

MORO

2025/01/11 03:13

早速のご回答ありがとうございます。 おっしゃる通り値を実行関数に渡して、関数内でバインドすることで対応できそうです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.34%

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

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

質問する

関連した質問