StrataFrame Forum

QueryInformation: SQL Generated for DB2 is incorrect

http://forum.strataframe.net/Topic11174.aspx

By PeterA - 8/28/2007

I'm hooking into DB2 and it returns a DB2 error when I start view the ASP page:



[DB2Exception (0x80004005): ERROR [42601] [IBM][DB2/NT] SQL0104N An unexpected token "[ID_SUPPLIER], [NM_SUPPLIER], [CD_COUNTRY], [IND_STATUS] FROM " was found following "SELECT DISTINCT ". Expected tokens may include: "". SQLSTATE=42601]




In this case, I believe the SQL is being generated incorrectly because of the square brackets around each field name - DB2 doesn't accept these. Are there any options I need to set on the QueryInformation object to change how it generates SQL and for what database?



Thanks in advance!

Peter
By PeterA - 8/28/2007

Some additional information. I was looking at the source code for the SqlDataSourceItem object and it looks like it will have this kind of trouble on the tables as well.



The following segment adds the fields to the query:





If QueryInfo.Fields.Count > 0 Then

For Each lcField In QueryInfo.Fields

loQuery.Append("[")

loQuery.Append(lcField)

loQuery.Append("], ")

Next



'-- Remove the last two characters ", "

loQuery.Length -= 2

Else

loQuery.Append("*")

End If





It's adding brackets regardless of the database type. Something similar happens when specifying table names:





loQuery.Append(" FROM [")

loQuery.Append(QueryInfo.TableSchema)

loQuery.Append("].[")

loQuery.Append(QueryInfo.TableName)

loQuery.Append("] ")





If the database is DB2 v8 (we've not upgraded to v9 yet, but the DB2 Express v9 on my development PC provides the same error), it can't use brackets around the table names either and the query will fail.



Thanks!



Peter
By Greg McGuffey - 8/28/2007

Brackets around SQL Server items is OK. This allows for non-compliant names to be used (such as names with spaces or that are key words).



Might be nice if there was a way to configure the data source to not use the brackets... Hehe
By PeterA - 8/29/2007

Greg McGuffey (08/28/2007)
Brackets around SQL Server items is OK. This allows for non-compliant names to be used (such as names with spaces or that are key words).



Might be nice if there was a way to configure the data source to not use the brackets... Hehe




Yes, it's OK to use square brackets around fields and tables on SQL Server. I imagine it's OK on Oracle, too (I don't have enough experience to confirm that), but DB2 v9 and DB2 v8 don't allow it. It causes a SQL error to be thrown. I also know of at least one other DB platform (it's not supported by this architecture) that would throw an error.


By StrataFrame Team - 8/29/2007

You are correct both correct.  The "identifier delimiter" used by the different databases for special names is like this:

SQL Server: [name]

Oracle: "name"

DB2: "name"

Access: [name]

So, knowing this, we took out all of the [] from the Db2DataSourceItem and replaced them with "".  Could you post the stack trace for the error you're getting?  It's odd that the Db2DataSourceItem is using [], so I need to track that one down.

By PeterA - 8/29/2007

Ben Chase (08/29/2007)
You are correct both correct.The "identifier delimiter" used by the different databases for special names is like this:



SQL Server: [name]



Oracle: "name"



DB2: "name"



Access: [name]



So, knowing this, we took out all of the [] from the Db2DataSourceItem and replaced them with "". Could you post the stack trace for the error you're getting? It's odd that the Db2DataSourceItem is using [], so I need to track that one down.




Here's the stack trace from my error page:



IBM.Data.DB2.DB2Command.a(CommandBehavior A_0, String A_1, DB2CursorType A_2, Boolean A_3, Boolean A_4, Boolean A_5, Int32 A_6) +3973

IBM.Data.DB2.DB2Command.a(CommandBehavior A_0, String A_1) +47

IBM.Data.DB2.DB2Command.ExecuteReader(CommandBehavior behavior) +93

IBM.Data.DB2.DB2Command.ExecuteDbDataReader(CommandBehavior behavior) +33

System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) +7

System.Web.UI.WebControls.SqlDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments) +2464

System.Web.UI.WebControls.Repeater.GetData() +50

System.Web.UI.WebControls.Repeater.CreateControlHierarchy(Boolean useDataSource) +232

System.Web.UI.WebControls.Repeater.OnDataBinding(EventArgs e) +53

System.Web.UI.WebControls.Repeater.DataBind() +72

System.Web.UI.WebControls.Repeater.EnsureDataBound() +55

System.Web.UI.WebControls.Repeater.OnPreRender(EventArgs e) +12

System.Web.UI.Control.PreRenderRecursiveInternal() +77

System.Web.UI.Control.PreRenderRecursiveInternal() +161

System.Web.UI.Control.PreRenderRecursiveInternal() +161

System.Web.UI.Control.PreRenderRecursiveInternal() +161

System.Web.UI.Control.PreRenderRecursiveInternal() +161

System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1360



Thanks!
By StrataFrame Team - 8/29/2007

Aha, you're not going through any SF stuff to get there.  You're using the System.Web.UI.WebControls.SqlDataSourceView class which is designed to work with SQL Server, so it's creating the query for SQL.  DB2 might have a corresponding ASP.NET control.  If it doesn't then you might need to fill a DataTable in code and use it to populate the grid (or whatever you're bound to).
By PeterA - 8/29/2007

Well, I've got it sort of working. I created a static SqlHandler object that is initialized when the request is started and retrieves a connection whenever necessary. Originally, I had it returning a SqlDataSourceItem object, but changed that to Db2DataSourceItem. I had though the SqlDataSourceItem was a generic object rather than one specific to SQL Server.



I've now got it connected in and pulling data like it should.



Thanks for your help!
By StrataFrame Team - 8/30/2007

Excellent.  Glad it's working for you Smile 

As for the objects, we tried to keep the names the same as the corresponding ADO.NET provider objects (except for a few cases where the data source uses OLE DB.

SqlDataSourceItem -> System.Data.SqlClient.SqlCommand

OracleDataSourceItem -> System.Data.OracleClient.OracleCommand

Db2DataSourceItem -> IBM.Data.DB2.DB2Command (technically this one accepts a factory, so you can use whatever provider is optimized for your database type since DB2 has several different versions of their ADO.NET provider and we didn't want to limit you)

VfpDataSourceItem -> System.Data.OleDb.OleDbCommand

AccessDataSourceItem -> System.Data.OleDb.OleDbCommand

By PeterA - 8/30/2007

Ben Chase (08/30/2007)
Excellent. Glad it's working for you Smile



As for the objects, we tried to keep the names the same as the corresponding ADO.NET provider objects (except for a few cases where the data source uses OLE DB.



SqlDataSourceItem -> System.Data.SqlClient.SqlCommand



OracleDataSourceItem -> System.Data.OracleClient.OracleCommand



Db2DataSourceItem -> IBM.Data.DB2.DB2Command (technically this one accepts a factory, so you can use whatever provider is optimized for your database type since DB2 has several different versions of their ADO.NET provider and we didn't want to limit you)



VfpDataSourceItem -> System.Data.OleDb.OleDbCommand



AccessDataSourceItem -> System.Data.OleDb.OleDbCommand




That's good to know and I'll have to keep it in mind. I'd probably have realized that if I'd worked in .NET technologies prior to now (I know more about PHP/MySQL applications than anything else at the moment).



Thanks!
By StrataFrame Team - 8/31/2007

I know more about PHP/MySQL applications than anything else at the moment

Mmm, the good old days.  That's where I started my SQL exploits.  Still to this day, I think LIMIT instead of TOP.

Don't worry about .NET, though, you'll get the hang of it quickly enough.