@Tejash's answer is brilliant but the query isn't optimizable. That matters if the Employee
table will be large.
There's presumably an index/PK on Employee.Id
. Using REGEXP_SUBSTR
means Oracle will ignore the index and scan the entire Employee
table looking for the IDs, evaluating REGEXP_SUBSTR
for each row.
Two optimizable approaches come to mind.
1. Don't use parameters for the Employee ID list
I know, sacrilege. But if the Employee ID list is a collection of valid numbers, for example List<int>
, int[]
, IEnumerable<long>
, etc., then the input is cleansed and there's no attack surface for SQL Injection.
// employeeIds is the list of IDs; must be vetted as valid numbers
string ids = string.Join(",", employeeIds);
string query = $"Select Name, Id from Employee where Id IN ({ids})";
Assuming employee IDs 1, 2 and 3, query
will have the following value:
Select Name, Id from Employee where Id IN (1, 2, 3)
2. Create a separate parameter for each Employee ID
Required if the Employee IDs aren't a collection of valid numbers, meaning any of the following:
- Employee IDs can have letters.
- Employee IDs are numbers but they're not validated anywhere.
- Employee IDs are numbers validated on the client side but not the server side.
Note: the code for setting parameter values may vary depending on the data access library used.
// employeeIds is a list of IDs; could be any value
int parmNumber = 0;
List<string> parms = new List<string>();
foreach (string id in employeeIds) {
string parmName = $":id{parmNumber++}"; // id0 or id1 or etc.
parms.Add(parmName);
// "command" is the OracleCommand/DbCommand/whatever instance
command.Parameters.Add(new OracleParameter(parmName, id));
}
string ids = string.Join(",", parms); // ":id0, :id1, etc."
string query = $"Select Name, Id from Employee where Id IN ({ids})";
Assuming employee IDs 1, 2 and 3, query
will have the following value, and the parameter values will be set to 1, 2 and 3 respectively:
Select Name, Id from Employee where Id IN (:id0, :id1, :id2)