Stored Procedure works fine from SQL Mgt Studio but throws Invalid Object name #AllActiveOrders from MVC app - asp.net

I can run the 'guts' of my stored procedure as a giant query.. just fine from SQL Management Studio. Furthermore, I can even right click and 'execute' the stored procedure - .. y'know.. run it as a stored procedure - from SQL Management Studio.
When my ASP.NET MVC app goes to run this stored procedure, I get issues..
System.Data.SqlClient.SqlException: Invalid object name '#AllActiveOrders'.
Does the impersonation account that ASP.NET runs under need special permissions? That can't be it.. even when I run it locally from my Visual Studio (under my login account) I also get the temp table error message.
EDIT: Furthermore, it seems to work fine when called from one ASP.NET app (which is using a WCF service / ADO.NET to call the stored procedure) but does not work from a different ASP.NET app (which calls the stored proc directly using ADO.NET)
FURTHERMORE: The MVC app that doesn't crash, does pass in some parameters to the stored procedure, while the crashing app runs the Stored Proc with default parameters (doesn't pass any in). FWIW - when I run the stored procedure in SQL Mgt. Studio, it's with default parameters (and it doesn't crash).
If it's of any worth, I did have to fix a 'String or Binary data would be truncated' issue just prior to this situation. I went into this massive query and fixed the temptable definition (a different one) that I knew to be the problem (since I had just edited it a day or so ago). I was able to see the 'String/Binary truncation' issue in SQL Mgt. Studio / as well as resolve the issue in SQL Mgt Studio.. but, I'm really stumped as to why I cannot see the 'Invalid Object name' issue in SQL Mgt. Studio

Stored procedures and temp tables generally don't mix well with strongly typed implementations of database objects (ado, datasets, I'm sure there's others).
If you change your #temp table to a #variable table that should fix your issue.
(Apparently) this works in some cases:
IF 1=0 BEGIN
SET FMTONLY OFF
END
Although according to http://msdn.microsoft.com/en-us/library/ms173839.aspx, the functionality is considered deprecated.
An example on how to change from temp table to var table would be like:
create table #tempTable (id int, someVal varchar(50))
to:
declare #tempTable table (id int, someval varchar(50))
There are a few differences between temp and var tables you should consider:
What's the difference between a temp table and table variable in SQL Server?
When should I use a table variable vs temporary table in sql server?

Ok. Figured it out with the help of my colleague who did some better Google-fu than I had done prior..
First, we CAN indeed make SQL Management Studio puke on my stored procedure by adding the FMTONLY option:
SET FMTONLY ON;
EXEC [dbo].[My_MassiveStackOfSubQueriesToProduceADigestDataSet]
GO
Now, on to my two competing ASP.NET applications... why one of them worked and one of them didn't? Under the covers, both essentially used an ADO.NET System.Data.SqlClient.SqlDataAdapter to go get the data and each performed a .Fill(DataSet1)
However, the one that was crashing was trying to get the schema in advanced of the data, instead of just deriving the schema after the fact.. so, it was this line of code that was killing it:
da.FillSchema(DataSet1, SchemaType.Mapped)
If you're struggling with this same issue that I've had, you may have come across forums like this from MSDN which are all over the internets - which explain the details of what's going on quite adequately. It had just never occurred to me that when I called "FillSchema" that I was essentially tripping over this same issue.
Now I know!!!

Following on from bkwdesign's answer about finding the problem was due to ADO.NET DataAdapter.FillSchema using SET FMTONLY ON, I had a similar problem. This is how I dealt with it:
I found the simplest solution was to short-circuit the stored proc, returning a dummy recordset FillSchema could use. So at the top of the stored proc I added something like:
IF 1 = 0
BEGIN;
SELECT CAST(0 as INT) AS ID,
CAST(NULL AS VARCHAR(10)) AS SomTextCol,
...;
RETURN 0;
END;
The columns of the select statement are identical in name, data type and order to the schema of the recordset that will be returned from the stored proc when it executes normally.
The RETURN ensures that FillSchema doesn't look at the rest of the stored proc, and so avoids problems with temp tables.

Related

Object Not Found when ASP.NET app is trying to access a stored procedure using global temp table

I have an ASP.NET application accessing an Oracle 12 database. I have written a stored procedure using a global temp table to help.
The global temp table is created with 'ON COMMIT DELETE ROWS'.
Basically the stored procedure does the following:
Get some data. Add a char column. Insert to the global temp table.
Use a key (in each row) to call another stored procedure.
The stored procedure returns a 'Y' or 'N'.
The return value will be updated to the corresponding row in the global temp table.
Once done all rows, return like this: open refcursor for select * from global_temp_table
I test the stored procedure. It works fine.
I then in my ASP.NET project, add another function in web service (asmx). I try to involve, but it says: "object not found".
I have read some posts and say change to 'ON COMMIT PRESERVE ROWS'. I don't want to leave data around. Is there any way to fix this issue? I have searched for sometime already.
[Edit] Other team mates have added many other stored procedures in database. They don't have to grant any right to it. The stored procedures are correctly executed when calling from web service. Of course, their sp do not use global temp table.
I have searched the web. I have seen similar posts out there. Calling an Oracle stored procedure using global temp table within ASP.NET will show the same error - object not found.
Anyway, I have found a way round. That is to use the WITH clause. Here is a reference link: https://oracle-base.com/articles/misc/with-clause
[/Edit]

Persistent error condition relating to Sqlite metadata

I've run into a very puzzling problem regarding a table in a Sqlite database.
The table has this simple DDL definition:
CREATE TABLE [MATable2] ([ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[AName] VARCHAR(20), [AMemo] MEMO)
Using XE6, DBExpress and v.3.8.5.0 of sqlite3.dll I've created a project
to investigate another SO q. The project (32-bit target) is deliberately as minimalist as I could make it, i.e. I've just pulled off the component palette a SqlConnection,
SqlQuery (which just does a 'SELECT * from [MATable2]'), DataSetProvider, CDS,
DataSource, DBGrid and DBNavigator wired up in left-to-right order as it were.
The code is equally minimalist, and I don't think I need show it because my
problem isn't with the code per se, which works fine.
The problem I've been getting is this: Every now and then, usually after I've made
some blunder that generates an exception (like calling CDS.Refresh in its ApplyUpdates event) the project (I would say "or its server" if the server in Sqlite's case weren't just
a dll) gets into an "error condition" which persists across restarting the XE6 IDE and
rebooting the machine. It manifests itself by the SqlQuery.Open generating an exception
complaining about a mismatch between the expected and actual field types, e.g. in the
case of the ID field, the exception will report that it was expecting a WideMemo field but received a LargeInt one instead - it's as if there is something off by one in the table's metadata as received by the SqlQuery.
Thinking this condition might be DBX-specfic, and something to do with Sqlite column
types really being thinly-disguised memo fields, I created a FireDac equivalent
project and that gets the error condition, too. Then, the condition clears,
as mysteriously as it appeared, usually after I delete the dataset components +
TFields and replace them.
So, my question is, does anyone know where can the error cause could be persisting, I mean
such that it survives IDE restarts and machine reboots? My first thought was in the DFM, because of what I've said about how it spontaneously clears. Next, I suspected the database itself, but it seems perfectly tickety-boo accessed, queried and recreated using two independent Sqlite utilities, Sqlite Expert and the Sqlite Manager add-in for Firefox. The OS reports the disk as w/out errors. I've looked for persisted info that might be the cause, in Ini files and the Registry, but found nothing obvious.

Populating ASP.NET SqlDataSource from a Firebird 2.0 Stored Procedure

I am working on a project where I do not have any control over the versions of products that I have been asked to work with.
I am building an ASP.NET user control. Data is retrieved via SqlDataSource controls working against Firebired 2.0 databases. Everything was fine until I needed to populate one of the SqlDataSource controls via a stored procedure rather than a SELECT statement.
I have verified that the procedure is returning data in EMS SQL Manager for Interbase and Firebird. However, when I set the SqlDataSource's SelectCommand property to EXECUTE PROCEDURE myProc and call Select(), I am getting no data.
My procedure takes no input parameters so it seems to me that it should be straight-forward.
The reality of the situation is that I could use a simple SELECT statement if I were able to move to even 2.1 as I would have access to the List() aggregate function, but that is not a possibility.
Does anyone have any experience trying to do this? Does the procedure call need to be modified in any way? Any help would be greatly appreciated.
If it is selectable stored procedure (it has SUSPEND command in it) then you should call it with SELECT statement, not with EXECUTE PROCEDURE statement. So set your SelectCommand to
SELECT * FROM spName
and it should work.
I would normally do this like so (against SQL Server) :
// set the SqlDataSource's SelectCommand to the *name* of the stored procedure
myDataSource.SelectCommand = "myProc";
// tell the SqlDataSource that this is a *stored procedure* now
myDataSource.SelectCommandType = CommandType.StoredProcedure;
Since your stored procedure takes no input parameters at all, this should really be all!
With SQL Server, selecting the data works just fine with this setup.

How to use variables in sqlite

Created the following code in SQL however need to use it in sqlite (phonegap specifically).
INSERT INTO actions(Action) VALUES ('Go to the pub');
SET #aid = LAST_INSERT_ID();
INSERT INTO statements(statement, Language) VALUES ('Have a pint', 'English');
SET #sid = LAST_INSERT_ID();
INSERT INTO Relationships(SID,AID) VALUES (#sid,#aid);
The issue we are having however is how to declare the variables in sqlite.
The LAST_INSERT_ID() will become last_insert_rowid(), however what is the sqlite version of SET #aid = ?
SQLite does not have variables.
In an embedded database such as SQLite, there is no separate server machine or even process, so it would not make sense to add a programming language to the DB engine when the same control flow and processing logic could be just as well done in the application itself.
Just use three separate INSERT statements.
(In WebSQL, the result object has the insertId property.)

MS Access CREATE PROCEDURE Or use Access Macro in .NET

I need to be able to run a query such as
SELECT * FROM atable WHERE MyFunc(afield) = "some text"
I've written MyFunc in a VB module but the query results in "Undefined function 'MyFunc' in expression." when executed from .NET
From what I've read so far, functions in Access VB modules aren't available in .NET due to security concerns. There isn't much information on the subject but this avenue seems like a daed end.
The other possibility is through the CREATE PROCEDURE statement which also has precious little documentation: http://msdn.microsoft.com/en-us/library/bb177892%28v=office.12%29.aspx
The following code does work and creates a query in Access:
CREATE PROCEDURE test AS SELECT * FROM atable
However I need more than just a simple select statement - I need several lines of VB code.
While experimenting with the CREATE PROCEDURE statement, I executed the following code:
CREATE PROCEDURE test AS
Which produced the error "Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'."
This seems to indicate that there's a SQL 'PROCEDURE' statement, so then I tried
CREATE PROCEDURE TEST AS PROCEDURE
Which resulted in "Syntax error in PROCEDURE clause."
I can't find any information on the SQL 'PROCEDURE' statement - maybe I'm just reading the error message incorrectly and there's no such beast. I've spent some time experimenting with the statement but I can't get any further.
In response to the suggestions to add a field to store the value, I'll expand on my requirements:
I have two scenarios where I need this functionality.
In the first scenario, I needed to enable the user to search on the soundex of a field and since there's no soundex SQL function in Access I added a field to store the soundex value for every field in every table where the user wants to be able to search for a record that "soundes like" an entered value. I update the soundex value whenever the parent field value changes. It's a fair bit of overhead but I considered it necessary in this instance.
For the second scenario, I want to normalize the spacing of a space-concatenation of field values and optionally strip out user-defined characters. I can come very close to acheiving the desired value with a combination of TRIM and REPLACE functions. The value would only differ if three or more spaces appeared between words in the value of one of the fields (an unlikely scenario). It's hard to justify the overhead of an extra field on every field in every table where this functionality is needed. Unless I get specific feedback from users about the issue of extra spaces, I'll stick with the TRIM & REPLACE value.
My application is database agnostic (or just not very religious... I support 7). I wrote a UDF for each of the other 6 databases that does the space normalization and character stripping much more efficiently than the built-in database functions. It really annoys me that I can write the UDF in Access as a VB macro and use that macro within Access but I can't use it from .NET.
I do need to be able to index on the value, so pulling the entire column(s) into .NET and then performing my calculation won't work.
I think you are running into the ceiling of what Access can do (and trying to go beyond). Access really doesn't have the power to do really complex TSQL statements like you are attempting. However, there are a couple ways to accomplish what you are looking for.
First, if the results of MyFunc don't change often, you could create a function in a module that loops through each record in atable and runs your MyFunc against it. You could either store that data in the table itself (in a new column) or you could build an in-memory dataset that you use for whatever purposes you want.
The second way of doing this is to do the manipulation in .NET since it seems you have the ability to do so. Do the SELECT statement and pull out the data you want from Access (without trying to run MyFunc against it). Then run whatever logic you want against the data and either use it from there or put it back into the Access database.
Why don't you want to create an additional field in your atable, which is atable.afieldX = MyFunc(atable.afield)? All what you need - to run UPDATE command once.
You should try to write a SQL Server function MyFunc. This way you will be able to run the same query in SQLserver and in Access.
A few usefull links for you so you can get started:
MSDN article about user defined functions: http://msdn.microsoft.com/en-us/magazine/cc164062.aspx
SQLServer user defined functions: http://www.sqlteam.com/article/intro-to-user-defined-functions-updated
SQLServer string functions: http://msdn.microsoft.com/en-us/library/ms181984.aspx
What version of JET (now called Ace) are you using?
I mean, it should come as no surprise that if you going to use some Access VBA code, then you need the VBA library and a copy of MS Access loaded and running.
However, in Access 2010, we now have table triggers and store procedures. These store procedures do NOT require VBA and in fact run at the engine level. I have a table trigger and soundex routine here that shows how this works:
http://www.kallal.ca/searchw/WebSoundex.htm
The above means if Access, or VB.net, or even FoxPro via odbc modifies a row, the table trigger code will fire and run and save the soundex value in a column for you. And this feature also works if you use the new web publishing feature in access 2010. So, while the above article is written from the point of view of using Access Web services (available in office 365 and SharePoint), the above soundex table trigger will also work in a stand a alone Access and JET (ACE) only application.

Resources