Error calling stored procedure in a database whose catalog name contains a space

Posts   
 
    
clint
User
Posts: 145
Joined: 15-Nov-2005
# Posted on: 17-Jan-2012 19:36:19   

Using LLBLGen Pro Version 2.6 Final (April 15th, 2009) Using Template: Adapter Target Platform: .NET 2.0 SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll File version 2.6.9.511

I've got a problem similar to the one mentioned in this thread: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=17014&HighLight=1

I call a stored procedure:


ActionProcedures.Usp_DeleteJournalEntries(batchSize, dateString, LLBLGenDataAccessAdapter.TheDataAccessAdapter);

LLBLGenDataAccessAdapter.TheDataAccessAdapter is the data access adapter.

Here's the usp_DeleteJournalEntries()


public static int Usp_DeleteJournalEntries(System.Int32 batchSize, System.String lessThanOrEqualToDate, DataAccessAdapter adapter)
{
    SqlParameter[] parameters = new SqlParameter[2];
    parameters[0] = new SqlParameter("@batchSize", SqlDbType.Int, 0, ParameterDirection.Input, true, 10, 0, "",  DataRowVersion.Current, batchSize);
    parameters[1] = new SqlParameter("@lessThanOrEqualToDate", SqlDbType.VarChar, 14, ParameterDirection.Input, true, 0, 0, "",  DataRowVersion.Current, lessThanOrEqualToDate);

    int toReturn = adapter.CallActionStoredProcedure("[GCSLRMS_Empty].[dbo].[usp_DeleteJournalEntries]", parameters);

    return toReturn;
}

You can see the LLBLGen code was generated using the database name "GCSLRMS_Empty". The customer that uses this program selects a SQL Server database to use at runtime. In this case, they chose a database with the catalog name "GCSLRMS Database". That name contains a space.

Earlier in the program, I use a CatalogNameOverwrite to use the selected database instead of "GCSLRMS_Empty"


CatalogNameOverwriteHashtable aCatalogNameOverwriteHashtable = new CatalogNameOverwriteHashtable();
aCatalogNameOverwriteHashtable.Add("GCSLRMS_Empty", databaseName);
_dataAccessAdapter = new DataAccessAdapter(databaseConnectionString, false, aCatalogNameOverwriteHashtable, null);

OK, back to the stored procedure. It calls CallActionStoredProcedure(). Here's a snippet of that code:


public virtual int CallActionStoredProcedure(string storedProcedureToCall, SqlParameter[] parameters)
{
    SqlCommand command = new SqlCommand(CreateCorrectStoredProcedureName(storedProcedureToCall));

    command.Connection = (SqlConnection)base.GetActiveConnection();

    ...
}

After creating the SqlCommand, the CommandText property looks like this: command.CommandText = "database.[dbo].[usp_DeleteJournalEntries]" This command won't work!

I want it to say: command.CommandText = "[GCSLRMS database].[dbo].[usp_DeleteJournalEntries]"

The problem happens in the LLBLGen code:


private string CreateCorrectStoredProcedureName(string storedProcedureName)
{
    DynamicQueryEngine dqe = (DynamicQueryEngine)CreateDynamicQueryEngine();
        string procName = dqe.GetNewPerCallStoredProcedureName(storedProcedureName);
                    
    return DynamicQueryEngine.GetNewStoredProcedureName(procName);
}

After calling dqe.GetNewPerCallStoredProcedureName(): procName = "gcslrms database.[dbo].[usp_DeleteJournalEntries]"

I don't understand why it didn't put square brackets around the catalog name like this: procName = "[gcslrms database].[dbo].[usp_DeleteJournalEntries]"

Without the square brackets around the catalog name, the next statement: DynamicQueryEngine.GetNewStoredProcedureName(procName) returns: "database.[dbo].[usp_DeleteJournalEntries]"

So how do I work around this problem?

I tried overriding "GCSLRMS_Empty" with "[GCSLRMS Database]", but that didn't work because other parts of the program would generate SQL like this that doesn't work: SELECT [[gcslrms_database]].[dbo].[name] FROM [[gcslrms_database]].[dbo].[Person]

clint
User
Posts: 145
Joined: 15-Nov-2005
# Posted on: 17-Jan-2012 19:39:11   

I suppose you could suggest that the user change their database name to not use a space. But that's kind of a hassle since they have a lot of other software that uses ODBC to connect to that same database. So they would have to go to all those machines and change the ODBC datasource.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 18-Jan-2012 06:24:23   

clint wrote:

I tried overriding "GCSLRMS_Empty" with "[GCSLRMS Database]", but that didn't work because other parts of the program would generate SQL like this that doesn't work: SELECT [[gcslrms_database]].[dbo].[name] FROM [[gcslrms_database]].[dbo].[Person]

What if you use the overwrite hashtable just for the adapter instance that will run the stored procedure? So, in that adapter instance you just call the stored procedure.

Another workaround is to create a subclass of DataAccessAdapter and override CallRetrievalStoredProcedure, then you can write your own code, which would be very similar to the one in the parent, but you could ignore some naming checks while writing the command text. Then you can use that "special" adapter when you incur in SP's calls.

I don't know whether this is something that should be fixed as it encourages a bad practice. I will ask anyway.

David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 18-Jan-2012 11:53:20   

Your runtime is very old, we had a lot of fixes in the runtime since then. According to the changelogs, this issue wasn't one of the fixes we applied, so it's not likely it will fix your problem, but it's recommended you upgrade to the latest v2.6 build of the runtime (with templates, just download the latest full installer from the customer area)

In v3 it does wrap the catalog name, but the pipeline was refactored there so we have to look whether v2.6 has the same code already. It might be it was a breaking change to fix. We'll check whether we can backport the change.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 18-Jan-2012 14:52:57   

Correction, it doesn't work in v3.1 either.

Workaround is: wrap the name in [] inside the overwrites, so do:


string toStore = databaseName;
if(!toStore.StartsWith("["))
{
    toStore = "[" + toStore + "]";
}
aCatalogNameOverwriteHashtable.Add("GCSLRMS_Empty", toStore);

Rather rudimentairy, but it should fix your problem.

We'll look into a fix for this.

(Edit): it's a breaking change, as the string changes which could affect software which assumes a given value. We'll fix it in v3.5. You should use the workaround specified above.

Frans Bouma | Lead developer LLBLGen Pro
clint
User
Posts: 145
Joined: 15-Nov-2005
# Posted on: 18-Jan-2012 17:57:51   

Frans,

I already did code like your workaround. The problem is that the program I wrote uses one global DataAccessAdapter. So when other parts of the program are running queries using that global DataAccessAdapter, LLBLGen generates code with double square brackets like I mentioned earlier.

Instead of using a separate DataAccessAdapter to call the stored procedure like daelmo suggested, I decided to just temporarily change the value in the CatalogNameOverwriteHasTable right before the stored procedure call and then restore the original value after.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 19-Jan-2012 11:36:11   

Of course... flushed The normal catalog overwrites do properly wrap the name, the proc names are the ones which aren't wrapped.

Hmm... I think it's sloppy that the names aren't wrapped, so we'll fix it in 3.5, but that's of course not something you can use today in v2.6. I also think your workaround could fail in some situations where you're not careful, and as it's our fault that you're in that situation, we'll see how we can fix it in v2.6 as well. Stay tuned.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 19-Jan-2012 12:31:39   

We have analyzed the risk factor of a breaking change and it's actually so rare we think it's irrelevant compared to the fact you have to create less optimal code to work with the system as-is, so we backported the fix from v3.5 back to 3.1, 3.0 and 2.6.

I've attached the SqlServer DQE which contains the fix. Be aware you're using an old ormsupportclasses dll, so it's highly recommended you upgrade to the latest build of v2.6 and then copy the attached dll on top of it to see whether the fix works in your situation.

Attachments
Filename File size Added on Approval
SD.LLBLGen.Pro.DQE.SqlServer.NET20.dll 53,248 19-Jan-2012 12:31.49 Approved
Frans Bouma | Lead developer LLBLGen Pro
clint
User
Posts: 145
Joined: 15-Nov-2005
# Posted on: 19-Jan-2012 16:05:49   

Wow! I'm impressed that you would backport a change. simple_smile

Thanks!

One of these days I'll get around to upgrading to a newer version (3.x) of LLBLGen, it's been on my "To Do" list for a while.

clint
User
Posts: 145
Joined: 15-Nov-2005
# Posted on: 09-Mar-2012 16:45:15   

I finally got around to upgrading to the latest build of LLBLGen Version 2.6. I am using the new SqlServer DQE with the fix. However, we still have a problem.

Before CallActionStoredProcedure created an SQLCommand where CommandText was "database.[dbo].[usp_DeleteJournalEntries]"

The database is called "GCSLRMS database", so it dropped the "GCSLRMS" portion of the name.

The new SQLServer DQE generates this SQLCommand CommandText: "[database].[dbo].[usp_DeleteJournalEntries]"

So it put square brackets around the database name, but AFTER it already dropped the "GCSLRMS" portion of the name.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 09-Mar-2012 18:58:01   

Just to be sure:

  • Did you test before the dll with the fix and it worked?
  • You are using the latest build, but you are doing the fixed DQE dll. I think that the fix should be present in the latest build. Please try using the latest shipped assemblies.

(Edit) I will try to reproduce it later today...

David Elizondo | LLBLGen Support Team
clint
User
Posts: 145
Joined: 15-Nov-2005
# Posted on: 09-Mar-2012 23:24:15   

daelmo wrote:

Just to be sure:

  • Did you test before the dll with the fix and it worked?

  • You are using the latest build, but you are doing the fixed DQE dll. I think that the fix should be present in the latest build. Please try using the latest shipped assemblies.

I installed the latest build of Version 2.6 the other day and then replaced the SQL Server DQE dll with the one Frans sent me.

The new dll only fixes half the problem. It now puts square brackets around the database name, but it still drops all the words except the last one in a multi-word database name.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 10-Mar-2012 06:51:55   

clint wrote:

I installed the latest build of Version 2.6 the other day and then replaced the SQL Server DQE dll with the one Frans sent me.

The new dll only fixes half the problem. It now puts square brackets around the database name, but it still drops all the words except the last one in a multi-word database name.

I tried to reproduce the issue with the latest RTL and the fix assembly posted by Frans. Now the CatalogName overloads from config works just fine. The problem you describe is when I specify a CatalogNameOverwriteHashtable, like in:

var catalogOverwrites = new CatalogNameOverwriteHashtable();
catalogOverwrites.Add("Northwind", "Northwind X");

// call sp with my overwrite rule
using (var adapter = new DataAccessAdapter(string.Empty, false, catalogOverwrites, null))
{
    var results = RetrievalProcedures.CustOrderHist("ALFKI", adapter);
}  

The proc name is executed as [X].[dbo].[...]. We will look into it.

David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 12-Mar-2012 12:32:11   

The fix for v3.x can't be applied to v2.6 as it requires a change in the ormsupportclasses and every DQE dll.

We'll fix it in the SQL Server DQE.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 12-Mar-2012 12:48:04   

v2.6 fix is attached.

V3.1 fix is in next build. v3.5 fix is in next beta/RC release.

Attachments
Filename File size Added on Approval
SD.LLBLGen.Pro.DQE.SqlServer.NET20.zip 16,161 12-Mar-2012 12:48.10 Approved
Frans Bouma | Lead developer LLBLGen Pro
clint
User
Posts: 145
Joined: 15-Nov-2005
# Posted on: 12-Mar-2012 19:26:13   

OK, that latest fix worked. simple_smile

Thanks!