patternsqlMinor
Parameterized Query in Access SQL
Viewed 0 times
sqlparameterizedqueryaccess
Problem
I am a beginner in Access SQL. I am in need of writing a parameter query for Access SQL and found a few tutorials and links for that but that wouldn't satisfy my requirement.
DB: Access DB
This updates a 'PD' column based on the values of 'OG', 'CPTY-BA' in an
Below is the VBA code with Access SQL with provided parameters. Is there any other way to write it in a single
```
ElseIf (outputColumn = "PD") Then
strSQL = "SELECT [OG], CIF,[CPTY-BA], CIF_2 FROM INPUT WHERE RUN_NUMBER='" + runNumber + "' ORDER BY CIF"
Set rs = CurrentDb.OpenRecordset(strSQL)
If Not (rs.EOF And rs.BOF) Then
Do Until rs.EOF
strOrigGroup = rs![Original Group]
strCIF = rs![CIF]
strCIF2 = rs![CIF_2]
strBaselAsset = rs![CPTY-BA]
If (strOrigGroup = "CB" Or strOrigGroup = "FID" Or strOrigGroup = "PB") Then
strSQL1 = " SELECT DISTINCT [INPUT].RUN_NUMBER, [INPUT].CIF, INPUT.CIF_2,[PD].[MID_PD] FROM [PD] INNER JOIN [INPUT] " + _
"ON [PD].CIF=[INPUT].CIF_2 WHERE [PD].[CIF]='" + strCIF2 + "' and [INPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL1
Set rs1 = CurrentDb.OpenRecordset(strSQL1)
If Not (rs1.EOF And rs1.BOF) Then
strPD = CDbl(rs1![MID_PD])
Else
strPD = "0.0229"
End If
strSQL = "update output set [PD] = '" + Format(strPD, "#.0000000000000") + "' WHERE [OUTPUT].[CIF]='" + CStr(strCIF) + "' AND [OUTPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL
CurrentDb.Execute (strSQL)
ElseIf (strBaselAsset = "BK" Or strBaselAsset = "BO" Or strBaselAsset = "SK") Then
strSQL1 = "SELECT DISTINCT [INPUT].RUN_NUMBER, [INPUT].CIF, [PD_MASTER_CPTY].[PD] F
DB: Access DB
This updates a 'PD' column based on the values of 'OG', 'CPTY-BA' in an
INPUT table. I need to calculate PD values from other reference tables 'PD', 'PD_MASTER_CPTY' and 'PD_MASTER_BG'.Below is the VBA code with Access SQL with provided parameters. Is there any other way to write it in a single
SELECT statement?```
ElseIf (outputColumn = "PD") Then
strSQL = "SELECT [OG], CIF,[CPTY-BA], CIF_2 FROM INPUT WHERE RUN_NUMBER='" + runNumber + "' ORDER BY CIF"
Set rs = CurrentDb.OpenRecordset(strSQL)
If Not (rs.EOF And rs.BOF) Then
Do Until rs.EOF
strOrigGroup = rs![Original Group]
strCIF = rs![CIF]
strCIF2 = rs![CIF_2]
strBaselAsset = rs![CPTY-BA]
If (strOrigGroup = "CB" Or strOrigGroup = "FID" Or strOrigGroup = "PB") Then
strSQL1 = " SELECT DISTINCT [INPUT].RUN_NUMBER, [INPUT].CIF, INPUT.CIF_2,[PD].[MID_PD] FROM [PD] INNER JOIN [INPUT] " + _
"ON [PD].CIF=[INPUT].CIF_2 WHERE [PD].[CIF]='" + strCIF2 + "' and [INPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL1
Set rs1 = CurrentDb.OpenRecordset(strSQL1)
If Not (rs1.EOF And rs1.BOF) Then
strPD = CDbl(rs1![MID_PD])
Else
strPD = "0.0229"
End If
strSQL = "update output set [PD] = '" + Format(strPD, "#.0000000000000") + "' WHERE [OUTPUT].[CIF]='" + CStr(strCIF) + "' AND [OUTPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL
CurrentDb.Execute (strSQL)
ElseIf (strBaselAsset = "BK" Or strBaselAsset = "BO" Or strBaselAsset = "SK") Then
strSQL1 = "SELECT DISTINCT [INPUT].RUN_NUMBER, [INPUT].CIF, [PD_MASTER_CPTY].[PD] F
Solution
Before we can do anything here really, we need to clean this up so we can understand exactly what's going on.
To start with, let's remove some duplication. This code is copy/pasted all over the place, but no matter what happens, it executes.
Next, give your SQL statement variables some meaningful names. I shouldn't have to keep reminding myself that
Next, I would separate the messy business of creating the string to be executed from the business of actually executing.
Which brings me to recommending that you use ADODB for this. The only time it's really important to stick with DAO is when you intend on binding a form to the resulting Recordset. Instead of concatenating all of these parameters into strings, you could instead be passing parameter into parameterized queries. It looks and reads much better than this.
To start with, let's remove some duplication. This code is copy/pasted all over the place, but no matter what happens, it executes.
If Not (rs1.EOF And rs1.BOF) Then
strPD = CDbl(rs1![PD])
Else
strPD = "0.0229"
End If
strSQL = "update output set [PD] = '" + Format(strPD, "#.0000000000000") + "' WHERE [OUTPUT].[CIF]='" + CStr(strCIF) + "' AND [OUTPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL
CurrentDb.Execute (strSQL)If (strOrigGroup = "CB" Or strOrigGroup = "FID" Or strOrigGroup = "PB") Then
strSQL1 = " SELECT DISTINCT [INPUT].RUN_NUMBER, [INPUT].CIF, INPUT.CIF_2,[PD].[MID_PD] FROM [PD] INNER JOIN [INPUT] " + _
"ON [PD].CIF=[INPUT].CIF_2 WHERE [PD].[CIF]='" + strCIF2 + "' and [INPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL1
Set rs1 = CurrentDb.OpenRecordset(strSQL1)
ElseIf (strBaselAsset = "BK" Or strBaselAsset = "BO" Or strBaselAsset = "SK") Then
strSQL1 = "SELECT DISTINCT [INPUT].RUN_NUMBER, [INPUT].CIF, [PD_MASTER_CPTY].[PD] FROM PD_MASTER_CPTY INNER JOIN INPUT ON [PD_MASTER_CPTY].COUNTERPARTY=INPUT.[CPTY-BA] WHERE [PD_MASTER_CPTY].[COUNTERPARTY]='" + strBaselAsset + "'AND [INPUT].CIF_2='" + CStr(strCIF2) + "' and [INPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL1
Set rs1 = CurrentDb.OpenRecordset(strSQL1)
Else
strSQL1 = "SELECT [INPUT].RUN_NUMBER, [INPUT].CIF,[PD_MASTER_BG].[PD] FROM [PD_MASTER_BG] INNER JOIN INPUT ON [PD_MASTER_BG].[BUSINESS_GROUP]=INPUT.[ORIGINAL GROUP] WHERE [PD_MASTER_BG].[BUSINESS_GROUP]='" + strOrigGroup + "'AND [INPUT].CIF_2='" + CStr(strCIF2) + "' and [INPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL1
Set rs1 = CurrentDb.OpenRecordset(strSQL1)
End If
If Not (rs1.EOF And rs1.BOF) Then
strPD = CDbl(rs1![PD])
Else
strPD = "0.0229"
End If
strSQL = "update output set [PD] = '" + Format(strPD, "#.0000000000000") + "' WHERE [OUTPUT].[CIF]='" + CStr(strCIF) + "' AND [OUTPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL
CurrentDb.Execute (strSQL)
rs.MoveNext
LoopNext, give your SQL statement variables some meaningful names. I shouldn't have to keep reminding myself that
strSQL1 is the select statement and strSQL is the update. Try selectSQL and updateSQL respectively.Next, I would separate the messy business of creating the string to be executed from the business of actually executing.
Private Function BuildSelectStatement(byval cif as string, byval runNumber as integer, Optional byval baselAsset as String) As String
...
End Function
....
selectSQL = BuildSelectStatement(strCIF2, runNumber)Which brings me to recommending that you use ADODB for this. The only time it's really important to stick with DAO is when you intend on binding a form to the resulting Recordset. Instead of concatenating all of these parameters into strings, you could instead be passing parameter into parameterized queries. It looks and reads much better than this.
Code Snippets
If Not (rs1.EOF And rs1.BOF) Then
strPD = CDbl(rs1![PD])
Else
strPD = "0.0229"
End If
strSQL = "update output set [PD] = '" + Format(strPD, "#.0000000000000") + "' WHERE [OUTPUT].[CIF]='" + CStr(strCIF) + "' AND [OUTPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL
CurrentDb.Execute (strSQL)If (strOrigGroup = "CB" Or strOrigGroup = "FID" Or strOrigGroup = "PB") Then
strSQL1 = " SELECT DISTINCT [INPUT].RUN_NUMBER, [INPUT].CIF, INPUT.CIF_2,[PD].[MID_PD] FROM [PD] INNER JOIN [INPUT] " + _
"ON [PD].CIF=[INPUT].CIF_2 WHERE [PD].[CIF]='" + strCIF2 + "' and [INPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL1
Set rs1 = CurrentDb.OpenRecordset(strSQL1)
ElseIf (strBaselAsset = "BK" Or strBaselAsset = "BO" Or strBaselAsset = "SK") Then
strSQL1 = "SELECT DISTINCT [INPUT].RUN_NUMBER, [INPUT].CIF, [PD_MASTER_CPTY].[PD] FROM PD_MASTER_CPTY INNER JOIN INPUT ON [PD_MASTER_CPTY].COUNTERPARTY=INPUT.[CPTY-BA] WHERE [PD_MASTER_CPTY].[COUNTERPARTY]='" + strBaselAsset + "'AND [INPUT].CIF_2='" + CStr(strCIF2) + "' and [INPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL1
Set rs1 = CurrentDb.OpenRecordset(strSQL1)
Else
strSQL1 = "SELECT [INPUT].RUN_NUMBER, [INPUT].CIF,[PD_MASTER_BG].[PD] FROM [PD_MASTER_BG] INNER JOIN INPUT ON [PD_MASTER_BG].[BUSINESS_GROUP]=INPUT.[ORIGINAL GROUP] WHERE [PD_MASTER_BG].[BUSINESS_GROUP]='" + strOrigGroup + "'AND [INPUT].CIF_2='" + CStr(strCIF2) + "' and [INPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL1
Set rs1 = CurrentDb.OpenRecordset(strSQL1)
End If
If Not (rs1.EOF And rs1.BOF) Then
strPD = CDbl(rs1![PD])
Else
strPD = "0.0229"
End If
strSQL = "update output set [PD] = '" + Format(strPD, "#.0000000000000") + "' WHERE [OUTPUT].[CIF]='" + CStr(strCIF) + "' AND [OUTPUT].RUN_NUMBER='" + runNumber + "'"
Debug.Print strSQL
CurrentDb.Execute (strSQL)
rs.MoveNext
LoopPrivate Function BuildSelectStatement(byval cif as string, byval runNumber as integer, Optional byval baselAsset as String) As String
...
End Function
....
selectSQL = BuildSelectStatement(strCIF2, runNumber)Context
StackExchange Code Review Q#92906, answer score: 3
Revisions (0)
No revisions yet.