View
214
Download
0
Category
Preview:
Citation preview
SQL DOM: Compile Time Checking of Dynamic SQL Statements
Russel A. McClureIngolf H. Krüger
ICSE 2005University of California, San Diego
Department of Computer Science and Engineering
“Impedance Mismatch” Huh?
• OO = Software Engineering Principles• Relational = Mathematical Principles.• Impedance Mismatch: An SQL “select” in Java.
– In OO you traverse pointers, and send messages.– In Relational, you apply operators to relations:
• Select• Cartesian Product• Project• Union• Set Difference
Tedious Composition of SQL statements
Challenge: generate a simple SQL query on customers relation:
SELECT * FROM CustomersWHERE companyName = ‘<company name>’AND …
public string GetCustomers(string companyName, …. ){
bool firstCondition = true;StringBuilder sql= new StringBuilder(“SELECT *
FROM Customers “);if ((companyName!= null) && (companyName.Length
> 0) {if (firstCondition) {
firstCondition=false;sql,Append (“ WHERE “);
} else sql.Append(“ AND”);
sql.Append(“CompnyName=‘”);sql.Append(companyName);sql.Append(“’”);
}return sql.ToString();
}
Tedious Composition of SQL statements
misspelled name !
SQL syntax errorCan you find the bugs?
(Sorry, the compiler won’t help you)
Type Translation Horrors
public string SetUnitsInStock (int productID, int unitsInStock)
{
string sql = “UPDATE Products “ + “ SET UnitsInStock = “ + unitsInStock.ToString() + “ WHERE ProductID = “ + productID.ToString();
return sql;
} UnitsInStock is 16-bit integer. Runtime error if
unitsInStock (32-bit integer) is too big.
The SQL DOM solution
database DOMsqldomgen
the SQL DOM generator
sqldomgen – an executable, executed against a database.
Output: a DLL (Dynamic Link Library). Classes are referred to
as SQL DOM – SQL Domain Object Model.
How about now?public string GetCustomers (string companyName,
… ){
CustomersTblSelectSQLStmt sql= new CustomersTblSelectSQLStmt ();
if ((companyName!= null) && (companyName.Length > 0){
sql.AddWhereCondition( new CompanyNameWhereCond(companyName));
}return sql.GetSQL();
}
The DOM works its wonders in mysterious ways…
3 steps for DOM generation:
• Obtain database schema (through methods from OLEDB provider)
• Iterate through tables and columns (produce source files)
• Compile… (produce DLL)
The Object Model
Three main types of classes:
• SQL statements– select– update– insert– delete
• columns• where conditions
SQL Statements
SQLStmt
InsertSQLStmt UpdateSQLStmtSelectSQLStmt
CustomersTblSelectSQLStmt OrdersTblSelectSQLStmt
CustomersTblSelectSQLStmt()
JoinToOrders()
JoinTo()
AddWhereCondition()
AddOrderBy()
OrdersTblSelectSQLStmt()
JoinToOrderDetails()
JoinToCustomers()
JoinTo()
…
Column classes
CustomersTblColumn
CustomersTblInsertColumn CustomersTblUpdateColumn
CustomersTblSelectColumn
Column
Remember “nasty bug”?
This is what would happen now
public string SetUnitsInStock(int productID, int unitsInStock)
{…sql.UnitsInStock = |
…}
Where condition classes
CustomersTblWhereCond
CustomerIDWhereCond CompanyNameWhereCond
WhereCond
So this the answer…
public string GetCustomers (string companyName, … )
{CustomersTblSelectSQLStmt sql= new
CustomersTblSelectSQLStmt ();if ((companyName!= null) && (companyName.Length > 0){
sql.AddWhereCondition( new
CompanyNameWhereCond(companyName));}return sql.GetSQL();
}
Advantages
• Problems solved:
– type mismatch
– syntax errors (and spelling errors)
– semantic (structural) errors
and more…
Databases Change!!
Question: What’ll happen when there is a change in the database?
Answer: Re-run sqldomgen. May get errors:
•No such class exists – if table/column is renamed/removed
•Data type conversion error – if data type of column is changed
•Missing constructor parameter – if a new column is added to a table
Convenient IDE
public string GetallCustomers()
{
new CustomersTblSelectSQLStmt( ECustomersTblColumns.CustomerID, ECustomersTblColumns.
…
SQL injection protection
example: malicious SQL statements inserted into database through web form.e.g. submission of parameter
“Bad Guy’ drop table Customers”
• non-string data types are now safe
• string types are checked and proofed
Disadvantages
We do not enjoy the full power of SQL.
• What about GROUP BY and aggregate functions?
• EXISTS keyword?
• Nested queries? Co-dependent queries?
Can we do this?
SELECT column1,column2
FROM Table T
WHERE column2 >
(SELECT AVG(column2)
FROM Table T1
WHERE T.column1=T1.column1)
Disadvantages
• Performance (??)
– Query generation takes up to x100 longer
– But…Actual figures are in thousands of ms per 10,000 generations of queries.
– Query generation time << query runtime
Other existing developments
• SQLJ/Embedded SQL – do not support dynamic SQL statements.
• Object/relational mapping and persistent object systems – reduce expressive power.
Conclusion
• Many runtime problems become compile-time problems.
• More convenient
• Less powerful
• Slight overhead
Recommended