Entity Framework & Oracle: Cannot Insert VARCHAR2 > 1,999 Characters - string

I created a 4,000-character VARCHAR2 field in an Oracle table. I am inserting string values into the field using LINQ to Entities with Visual Studio 2010, .NET Framework 4, and ODAC 11.2 Release 4 and Oracle Developer Tools for Visual Studio (11.2.0.3.0). When I try to insert a string value greater than 1,999 characters, I get the following inner exception:
Oracle.DataAccess.Client.OracleException
ORA-00932: inconsistent datatypes: expected - got NCLOB
However, I can insert a 4,000 character string value into the field without any issue when doing so using SQL Developer.
There is a known ODAC bug (source #2) in which there is a 2,000 character limit when saving to an XMLTYPE field, but I am not saving to an XMLTYPE field. I have Oracle.DataAccess 2.112.3.0 in my GAC, and I considered updating to release 5 (11.2.0.3.20) of the aforementioned Oracle software, but "Oracle Developer Tools for Visual Studio" is the only component that appears to have been updated from release 4, and I believe that "Oracle Data Provider for .NET 4" is the component that needs updating. In my .NET project, System.Data.Entity and System.Data.OracleClient are both runtime version 4.0.30319.
Anyway, I am just wondering if anyone else has encountered this error, and if so, if any solution has been found - aside from the one in the Oracle forum thread that is linked above that proposes using stored procedures as a workaround. Google tells me that people are encountering this error only when working with XMLTYPE fields, but I can't be the only person who is encountering this error when working with a VARCHAR2 field, can I?
(FWIW, I am also hoping to receive a response to my post as user "997340" in the Oracle forum thread that is linked above. If I receive a useful response, I'll be sure to share the knowledge on this end.)
EDIT: In case it helps, below are the two blocks in my code that are failing. I created the second block when troubleshooting the first, just to see if there was any difference. I get the exception when checking to see if the string values were already inserted (the "if" statements), and when actually inserting the string values (the "AddObject" statements).
1:
if (!(from q in db.MSG_LOG_MESSAGE where q.MESSAGE == msg select q.MESSAGE).Any())
{
db.MSG_LOG_MESSAGE.AddObject(new MSG_LOG_MESSAGE { MESSAGE = msg });
db.SaveChanges();
}
2:
if (!db.MSG_LOG_MESSAGE.Any(q => q.MESSAGE == msg))
{
db.MSG_LOG_MESSAGE.AddObject(new MSG_LOG_MESSAGE { MESSAGE = msg });
db.SaveChanges();
}
APRIL 3 UPDATE:
I was able to trace the SQL that is being sent to Oracle from the "if" statement in the first code block above. Here it is:
SELECT
CASE WHEN ( EXISTS (SELECT
1 AS "C1"
FROM "SEC"."MSG_LOG_MESSAGE" "Extent1"
WHERE ("Extent1"."MESSAGE" = :p__linq__0)
)) THEN 1 WHEN ( NOT EXISTS (SELECT
1 AS "C1"
FROM "SEC"."MSG_LOG_MESSAGE" "Extent2"
WHERE ("Extent2"."MESSAGE" = :p__linq__0)
)) THEN 0 END AS "C1"
FROM ( SELECT 1 FROM DUAL ) "SingleRowTable1" ;
Unfortunately, the DBA that I worked with did not provide me with the value of the "p_linq_0" parameter, but as previously stated, when it is over 1,999 characters, an exception occurs. (When this SQL was traced, I passed a 4,000-character string as the parameter, and of course an exception occurred.) The DBA also mentioned something about certain SQL clients - such as SQLPlus - not being able to handle VARCHAR2s over 2,000 characters. I did not entirely follow. Whether using SQLPlus, SQL Developer, or any other tool, Oracle is still going to be querying a 4,000-character VARCHAR2 field. Plus, my magic number is 1,999 characters; not 2,000 characters. Did the DBA perhaps mean there is a limitation with how many characters can be in a parameter? More importantly, when I execute this SQL in SQL Developer and I enter a 4,000-character string for the parameter, it works perfectly. So I am still utterly confused about why it is not working via LINQ to Entities. I also tried the following code in my program to run a similar query with a 4,000-character string in the "msg" variable, which worked perfectly as well:
using Oracle.DataAccess;
using Oracle.DataAccess.Client;
using System.Data;
...
OracleConnection conn = new OracleConnection("Data Source=[MASKED];User Id=[MASKED];Password=[MASKED]");
conn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT message FROM msg_log_message WHERE message = '" + msg + "'";
cmd.CommandType = CommandType.Text;
OracleDataReader dr = cmd.ExecuteReader();
dr.Read();
string result1 = dr.GetString(0);
conn.Dispose();
For now, I am still pointing fingers at ODAC being buggy as it pertains to LINQ to Entities...

The latest ODP.NET documentation - for "11.2 Release 5 Production (11.2.0.3.0)" from September 2012 - states the following known issue under the "Entity Framework Related Tips, Limitations and Known Issues" section, which addresses the error from the "if" statements in the question's code blocks:
An "ORA-00932 : inconsistent datatypes" error can be encountered if a string of 2,000 or more characters, or a byte array with 4,000 bytes or more in length, is bound in a WHERE clause of a LINQ/ESQL query. The same error can be encountered if an entity property that maps to a BLOB, CLOB, NCLOB, LONG, LONG RAW, XMLTYPE column is used in a WHERE clause of a LINQ/ESQL query.
Older ODP.NET documentation - for "Release 11.2.0.3.0 Production" from May 2011 - states the same known issue, so apparently this has been a known issue for a while.
Neither of the aforementioned documentation mentions encountering the same error from the "AddObject" statements in the question's code blocks, but that issue is very similar to another known issue for XMLType fields that is mentioned:
An "ORA-00932: inconsistent datatypes: expected - got NCLOB" error will be encountered when trying to bind a string that is equal to or greater than 2,000 characters in length to an XMLType column or parameter. [Bug 12630958]

Related

Not getting results from IHP DataSync despite setting Row Level Policy

I want to use DataSync on my current application, using IHP 0.16. I believe I have followed all the installation steps in FrontController and Routes.
I have a characters table with a user_id column connected to the users table. I have set the policy on the characters table resulting in this generated SQL:
CREATE POLICY "Users can manage their characters" ON characters USING (user_id = ihp_user_id()) WITH CHECK (user_id = ihp_user_id());
ALTER TABLE characters ENABLE ROW LEVEL SECURITY;
Trying to run this in the JavaScript console
await query("characters").fetch()
I get this error in JavaScript output:
And this error in IHP output:
Query (2.119753ms): "SELECT relrowsecurity FROM pg_class WHERE oid = ?::regclass" ["characters"]
Query (0.111442ms): "SET LOCAL ROLE ?" [Identifier {fromIdentifier = "ihp_authenticated"}]
Query (0.130888ms): "SET LOCAL rls.ihp_user_id = ?" Only {fromOnly = Just 0d7b46b1-bcb4-46a2-bf77-ad27dace8416}
FormatError {fmtMessage = "1 single '?' characters, but 3 parameters", fmtQuery = "SELECT ? FROM ??", fmtParams = ["*","characters",""]}
This seems to be another error than the row level security error in the DataSync tutorial in the IHP docs. Any idea on what causes this error?
This is a known bug in IHP v0.16.0. It's already fixed in master
It's best to use IHP DataSync with the version mentioned in the introduction text at https://ihp.digitallyinduced.com/Guide/realtime-spas.html :)
There's btw a workaround for the bug if you don't want to upgrade: You always need to specify an order by, like await query("characters").orderBy('createdAt').fetch()

What does SQLEXPR Installer return code -2068578304 mean?

I am working on an installer project where we are replacing an old WISE based installer with innosetup.
One of the install scripts that is being ported to the new installer kicks of SQLEXPR.exe which is SQL Server Express.
During testing some computers get %ERRORLEVEL% = -2068578304
A bit of googling and I have been unable to work out the exact meaning. This is not in the range of error codes produced by MSI based installers. Does anyone have any idea what the cause of error here is and how to correctly parse it? I am seeing other large negative error codes that can be split into multiple pieces. e.g. exit code and facility code? any ideas?
After finding the log file, I've found a bit more info. And when converting that number to hex I can now see the problem. The batch file that is used to kick off the SQL Server Express installation is treating the result as a 32bit number but it's really a 16bit one. So if I mask -2068578304 to 0xffffffff
I will get the result 0x84b40000. The script looks currently looks at the bottom 4 bits to determine error or success (this is zero) so the question now becomes what does the Facility Code mean? as it appears it largely installed but the default instance is missing.
I guess I'm really wanting to know what values Facility Code can be returned. Our installation script is just looking at ErrorCode but that is not enough in other words. Is there a list of descriptions somewhere for FacilityCode?
Update:
It turns out that this is a problem with SQL2012 and earlier that the actual ErrorCode is not propagated to the SQLEXPR return code. It should really return the inner result 0x851a0013. SQL2014 and newer does the right thing.
Exception summary:
The following is an exception stack listing the exceptions in outermost to inner
most order
Inner exceptions are being indented
Exception type: Microsoft.SqlServer.Chainer.Infrastructure.InputSettingValidatio
nException
Message:
The specified sa password does not meet strong password requirements. Fo
r more information about strong password requirements, see "Database Engine Conf
iguration - Account Provisioning" in Setup Help or in SQL Server 2012 Books Onli
ne.
HResult : 0x84b40000
FacilityCode : 1204 (4b4)
ErrorCode : 0 (0000)
Data:
SQL.Setup.FailureCategory = InputSettingValidationFailure
DisableWatson = true
Stack:
at Microsoft.SqlServer.Chainer.Infrastructure.InputSettingService.LogAll
ValidationErrorsAndThrowFirstOne(ValidationState vs)
at Microsoft.SqlServer.Configuration.SetupExtension.ValidateFeatureSetti
ngsAction.ExecuteAction(String actionId)
at Microsoft.SqlServer.Chainer.Infrastructure.Action.Execute(String acti
onId, TextWriter errorStream)
at Microsoft.SqlServer.Setup.Chainer.Workflow.ActionInvocation.ExecuteAc
tionHelper(TextWriter statusStream, ISequencedAction actionToRun, ServiceContain
er context)
Inner exception type: Microsoft.SqlServer.Configuration.SqlEngine.Validation
Exception
Message:
The specified sa password does not meet strong password requirem
ents. For more information about strong password requirements, see "Database Eng
ine Configuration - Account Provisioning" in Setup Help or in SQL Server 2012 Bo
oks Online.
HResult : 0x851a0013
FacilityCode : 1306 (51a)
ErrorCode : 19 (0013)

Sharepoint Business Data List Behavior

This is a multi faceted question, but any help is appreciated
Background:
I have a Application Definition with 6 entities using SSO
The database back end is Firebird through ODBC
All the data is coming from stored procedures
Questions:
1 While trying to implement one or any of the entities from the BDC in a Business Data List web part I get the following error: "An error occurred while retrieving data from . Administrators, see the server log for more information." It only happens when I have fields that are null, in this instance a field that was declared as a string.
2.When I check the logs, it's a System.OverFlowException.
3.If I change it so the output from the procedure is a blank string, I suddenly get "The title property of entity is set to an invalid value"
4.The error from the logs after changing to a blank string is "Exception handed to HandleXslException.HandleException System.ArgumentException: '.', hexadecimal value 0x00, is an invalid character"
What gives? It worked last night without issue until a record appeared that had a null value in one of the string field. Now, even replacing the null value with something generic is still giving me the title property invalid error.
Most puzzling: If I change the query so that the rows with what would be a null or blank string aren't in the query, the error goes away. But, if I add them back and replace the null string with anything, the error comes back. What the !##$? How does it know I've replaced a null value with something else before the records are returned to the XmlReader?
I've run into this exact scenario and it brought back some angry/confused moments. As you said in your comment:
I set the encoding to be unicode on all varchar and char outputs and it fixed it. The lack of encoding caused there to be null characters (not a null record, but one null character) for that column and Sharepoint could not parse the field. Changed the encoding, and everything works.
It took me a couple days of swearing at the computer before we took it down to the metal and discovered the unicode issue. I don't even know when it changed but we realized the same thing and all was right with the world again.

SubSonic SQL CE Error

I have an old c# project which currently runs on a SQL CE database. I decided yesterday that I would like to use SubSonic to generate a DAL for me as I have used SubSonic a lot in my other projects (with a standard MS SQL database backend) and I love it's ease of use.
Everything seems fine, I can create and delete records but as soon as I update a record using the Save() method an error it thrown:
Example:
Person person = new Person();
person.Name = "Robert";
person.Save(); // Works fine, record is saved
person.Name = "Robert - Updated";
person.Save(); // Fails with error below
"There was an error parsing the query. [ Token line number = 1, Token line offset = 61, Token in error = SELECT ]"
When I update a record by creating a new Query and setting the QueryType to Update, it also seems to be working as expected.
Any ideas?
Thanks
Try to get hold of the generated SQL to see what gets executed.
My guess is that SubSonic escapes column or table names with [ and ], which is fine for a full-blown SQL Server, but its CE counterpart does not support that.
My guess is that Subsonic is trying to execute several SQL statments in a single command - this is not supported by SQL Compact

Subsonic 3.0 SQLite FormatException parsing DateTime?

I have an MS Access database, which I have converted to an SQLite database. I have SubSonic setup and working, and I can pull data out of the database successfully into a WinForms app using ActiveRecord. All except for one table.
I get a FormatException, "String was not recognized as a valid DateTime". The format of the date column in the database is DD/MM/YYYY.
I'm not even trying to do anything too complicated:
var allOrders = order.All();
foreach (order o in allOrders)
{
listBox1.Items.Add(string.Format("{0} - {1}", o.OrderDate.HasValue ? o.OrderDate.Value.ToShortDateString() : string.Empty, o.Product));
}
I'm not exactly sure why the problem is manifesting in the first place :(
SQLite has "interesting" ways of formatting dates - you have to be very, very sure that you're getting back what you think you are because normally it's not DD/MM/YYYY - it's the opposite if I recall.

Resources