Generate SQL query for column matching


/ Published in: Visual Basic
Save to your folder(s)

Written as reply to question on ittoolbox.com:"I need to execute a query in vb which can find multiple value provided by the user to find from a single column of a table."
[http://database.ittoolbox.com/groups/technical-functional/sql-l/query-to-find-multiple-values-in-single-column-5729534]

DISCLAIMERS: (1) this code is VBA/Excel, not Visual Basic; (2) this was tested in Excel; (3) the SQL was NOT tested against MS Access (the target dbms); (4) I am not a VB coder or an MS Access user -- I'm a programmer and a SQL user; (5) this code is specific to the question asked, but can be a model for similar SQL-generation problems

This code uses 3 functions:
* buildSQL -- takes user input, calls the other two functions, produces a ready-to-execute SQL SELECT statement
* buildMatchCountSQL -- takes user input, produces a select list item for inclusion in the SELECT clause
* buildMatchSQL -- takes user input, produces a predicate for inclusion in the WHERE clause

The code can be tested using the TEST() function, which prompts for user input and produces the SQL SELECT statement.

--bryan watson, May 12,2015


Copy this code and paste it in your HTML
  1. Function buildMatchCountSQL(user_input As String) As String
  2. ' produce a SQL select list item of:
  3. ' , CASE WHEN PO.Pname LIKE '*abc*' THEN 1 ELSE 0 END
  4. ' + CASE WHEN PO.Pname LIKE '*def*' THEN 1 ELSE 0 END
  5. ' + CASE WHEN PO.Pname LIKE '*xyz*' THEN 1 ELSE 0 END
  6. ' AS matches
  7. ' Parse the user input into an array of match words
  8. ' replace commas with spaces so there is only 1 type of delimiter
  9. Dim aString As String
  10. aString = Replace(user_input, ",", " ")
  11. ' put all words in a temporary array
  12. Dim TempArray() As String
  13. TempArray() = Split(aString, " ")
  14. ' build SQL predicates ignoring any empty strings
  15. Dim intCount As Integer
  16. intCount = 0
  17. For Each Word In TempArray
  18. If Word <> "" Then
  19. ' remove leading/trailing blanks, convert word to uppercase,
  20. ' wrap word in quotes and wildcard characters
  21. Word = "'*" & Trim(UCase(Word)) & "*'"
  22. ' start selection with comma, join with plus sign
  23. If intCount = 0 Then
  24. buildMatchCountSQL = ", "
  25. Else
  26. buildMatchCountSQL = buildMatchCountSQL & " + "
  27. End If
  28. buildMatchCountSQL = buildMatchCountSQL & "CASE WHEN PO.Pname LIKE " & Word
  29. buildMatchCountSQL = buildMatchCountSQL & " THEN 1 ELSE 0 END "
  30. intCount = intCount + 1
  31. End If
  32. Next
  33. ' add the column name (unless there are no matches)
  34. If buildMatchCountSQL <> "" Then
  35. buildMatchCountSQL = buildMatchCountSQL & " AS matches"
  36. End If
  37. End Function
  38.  
  39. Function buildMatchSQL(user_input As String) As String
  40. ' produce a SQL predicate of:
  41. ' AND ( PO.Pname LIKE '*abc*'
  42. ' OR PO.Pname LIKE '*def*'
  43. ' OR PO.Pname LIKE '*xyz*'
  44. ' )
  45. ' Parse the user input into an array of match words
  46. ' replace commas with spaces so there is only 1 type of delimiter
  47. Dim aString As String
  48. aString = Replace(user_input, ",", " ")
  49. ' put all words in a temporary array
  50. Dim TempArray() As String
  51. TempArray() = Split(aString, " ")
  52. ' build SQL predicates ignoring any empty strings
  53. Dim intCount As Integer
  54. intCount = 0
  55. For Each Word In TempArray
  56. If Word <> "" Then
  57. ' remove leading/trailing blanks, convert word to uppercase,
  58. ' wrap word in quotes and wildcard characters
  59. Word = "'*" & Trim(UCase(Word)) & "*'"
  60. ' wrap predicate list in parentheses, join with OR
  61. If intCount = 0 Then
  62. buildMatchSQL = " AND ( "
  63. Else
  64. buildMatchSQL = buildMatchSQL & " OR "
  65. End If
  66. buildMatchSQL = buildMatchSQL & "PO.Pname LIKE " & Word
  67. intCount = intCount + 1
  68. End If
  69. Next
  70. ' add the closing parenthesis (unless there are no predicates)
  71. If buildMatchSQL <> "" Then
  72. buildMatchSQL = buildMatchSQL & " )"
  73. End If
  74. End Function
  75.  
  76. Function buildSQL(user_input As String) As String
  77. buildSQL = "SELECT PO.PCode, PO.Pname, PPLO.Price,PO.status, PPLO.Efct_Date, PO.Hlink,PO.website"
  78. ' add match count to the SQL select column list
  79. ' (if there are no words to match, this will be an empty string)
  80. buildSQL = buildSQL & buildMatchCountSQL(user_input)
  81. buildSQL = buildSQL & " FROM Pmast_Others PO"
  82. buildSQL = buildSQL & " INNER JOIN Product_Price_List_Others PPLO"
  83. buildSQL = buildSQL & " ON PO.[PCode] = PPLO.[PCode]"
  84. buildSQL = buildSQL & " WHERE PO.status is NULL"
  85. ' add conditions to the SQL predicate list
  86. ' (if there are no words to match, this will be an empty string)
  87. buildSQL = buildSQL & buildMatchSQL(user_input)
  88. End Function
  89.  
  90. Function TEST() as String
  91. Dim user_input As String
  92. Dim strSQL As String
  93. Dim newLine As String
  94. newLine = Chr(13)
  95.  
  96. user_input = InputBox("Enter terms separated by commas or spaces", "User Input", "")
  97. strSQL = buildSQL(user_input)
  98. Dim x As String
  99. If user_input = "" Then
  100. user_input = "(empty string)"
  101. End If
  102. x = "'" & user_input & "' => " & newLine & newLine & strSQL
  103. x = InputBox(x, "SQL Query String Result", x)
  104. TEST = strSQL
  105. End Function

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.