Unspecified Error when trying to ExecuteReader on SQL Server CE - c#

I had implemented a database storage on my app for Windows Mobile 6.5 using SQL Server CE.
Had managed to install the SQL Server CE CAB file on the device (Motorola MC65).
Managed to create database file, and create tables. Insert also can be executed.
However when I try to run ExecuteReader() to read records, I hit the following error:
Error Code: 80004005
Message : Unspecified error
Minor Err.: 25534
Source : SQL Server Compact ADO.NET Data Provider
No idea why this is happening. Since insert can be executed I thought this should not be a connection or privilege issue.
The reading code is as below:
openConnection();
SqlCeCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT NAME FROM GROUP_INFO ORDER BY NAME ";
SqlCeDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
string groupName = reader.GetString(0);
listGroup.Add(groupName);
}
The exception is thrown on the line where cmd.ExecuteReader() is executing.
Any pointers are appreciated. Thanks.

Implement proper error handling for SqlCeExceptions! The error is documented here https://technet.microsoft.com/en-us/library/ms172350(v=sql.110).aspx
Large objects (ntext and image) cannot be used in ORDER BY clauses.
Maybe you should redefine the column as nvarchar(4000) (it is currently ntext), or rephrase the query using:
ORDER BY CAST(Name as nvarchar(4000))
But this will cause a table scan

Related

Azure Connection for Data Reader

I've created an App and have created the Azure database which I can connect to and populate with no issues.
I have a SQL query that I have hard coded in to a controller and view using a Data Reader, as there's a Pivot and it was the only way I could get it to work correctly.
con.Open();
com.Connection = con;
com.CommandText = "SELECT * FROM [DatabaseName].[dbo].[TABLE]"
dr = com.ExecuteReader();
while (dr.Read())
{
// Assign the variables
}
[DatabaseName].[dbo].[TABLE] This is the part where I'm having issues, throwing an invalid Object name for the Table, it works locally but not when trying to connect to Azure.
Can someone help me with a fix please?
Many thanks
Cross-database and cross-instance queries using three or four part names are not supported in Azure Sql Database. The differences in TSQL are documented here https://learn.microsoft.com/en-us/azure/azure-sql/database/transact-sql-tsql-differences-sql-server?view=azuresql

Parameter Query using SQLite

I am trying to make a SQLite SQL query using parameters and for some reason its not working (i have done this with an OLE db before successfully). I took the below syntax from a google search but doesnt seem to be working.
It doesnt seem to like my command.perameter.add line and its giving me a "SQLite is not accessible due to its protection level" error.
I imagine its me converting from OLE to SQLlite syntax that is causing the issue but im not sure. Any ideas? My code is as below:
string sql = "INSERT INTO Jobs (jEnquiryNumber) VALUES (#jEnquiryNumber)";
MessageBox.Show(sql);
SQLiteCommand command = new SQLiteCommand(sql, dbConnectString);
using (command)
{
command.Parameters.Add("#jEnquiryNumber", SQLiteType.Text).Value = textBox1.Text;
}

How to Select an out parameter from a MySql Procedure in .net

Assume we have a stored procedure like so
CREATE PROCEDURE CopyValue(IN src INT, OUT dest INT)
BEGIN
SET dest = src;
END
I want to call this from a .net app (assume connection etc created successfully)
var sql = "call CopyValue(100, #destValue); select #destValue as Results;";
The string in the above statement works perfectly well when called in MySql Workbench.
However this - obviously - fails with "MySqlException: Parameter '#destValue' must be defined" when executed on a MySqlCommand object in .net
How do I arrange this statement so I can capture an output parameter from an existing procedure?
NB: I'm running against MySql 5.6, which I can't upgrade at this time.
NB Calling the procedure directly with CommandType.StoredProcedure goes against company guidelines.
By default, user-defined variables aren't allowed in SQL statements by MySQL Connector/NET. You can relax this restriction by adding AllowUserVariables=true; to your connection string. No modifications to your SQL or how you're executing the MySqlCommand should be necessary.
For information about why this is the default, you can read the research on this MySqlConnector issue (which also has the same default behaviour, but a much better error message that will tell you how to solve the problem): https://github.com/mysql-net/MySqlConnector/issues/194
A colleague (who wishes to remain anonymous) has answered this perfectly. Essentially put backticks ` after the # and at the end of the variable name e.g.
#`MyParam`
A fully working example.
static void Main(string[] args)
{
using var con = new MySql.Data.MySqlClient.MySqlConnection("Data Source=localhost; User Id=...;Password=...;Initial Catalog=...");
con.Open();
using var cmd = con.CreateCommand();
cmd.CommandText = "call CopyValue2(100, #`v2`); select #`v2` as Results;";
using var reader = cmd.ExecuteReader();
if (reader.Read())
Console.WriteLine($"Copied Value {reader.GetInt64(0)}");
}
Thanks OG :)

Minimum access levels to run MySql stored procedure

I am trying to setup my .NET 4.7.1 program that is connecting to a MySQL database 8.0 to use the minimum privileges to run.
The .NET program is using MySql.Data to make connection. The minimum right for a user to execute a stored procedure is typically only EXECUTE privilege. This works fine from MySQL workbench or command line.
Upon running the .NET program this does return the following exception:
System.Data.SqlTypes.SqlNullValueException: 'Data is Null. This method or property cannot be called on Null values.'
To make it easy, I have create a very small demo program to demonstrate the issue.
Setup of the database:
CREATE DATABASE Spike;
CREATE PROCEDURE TestAccess()
BEGIN
END;
CREATE USER Spike#localhost IDENTIFIED WITH mysql_native_password BY 'sample';
GRANT EXECUTE ON PROCEDURE `TestAccess` TO Spike#localhost;
Setup program code:
static void Main(string[] args)
{
using (MySqlConnection conn = new MySqlConnection("Server=localhost;Database=Spike;uid=Spike;pwd=sample"))
{
conn.Open();
Console.WriteLine("Connection open");
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = "TestAccess";
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
Console.WriteLine("Query executed");
}
Console.ReadKey();
}
The crash happens at the line cmd.ExecuteNonQuery();
The stack from the crash is interesting, since it seems to indicate that the information_schema is queried. When logging all statements I can see that the last statement before the exception is:
SELECT * FROM information_schema.routines WHERE 1=1 AND routine_schema LIKE 'Spike' AND routine_name LIKE 'TestAccess'
I cannot grant different rights on information_schema, but I could give more rights on the stored procedure to make more information visible in the routines table, this feels wrong however. Simple tests with granting CREATE and ALTER access also did not work.
Is there something else I can do, without granting too much privileges?
This appears to be a bug in Connector/NET, similar to bug 75301 but a little different. When it's trying to determine parameter metadata for the procedure, it first creates a MySqlSchemaCollection named Procedures with all metadata about the procedure. (This is the SELECT * FROM information_schema.routines WHERE 1=1 AND routine_schema LIKE 'Spike' AND routine_name LIKE 'TestAccess' query you see in your log.)
The Spike user account doesn't have permission to read the ROUTINE_DEFINITION column, so it is NULL. Connector/NET expects this field to be non-NULL and throws a SqlNullValueException exception trying to read it.
There are two workarounds:
1) The first, which you've discovered, is to set CheckParameters=False in your connection string. This will disable retrieval of stored procedure metadata (avoiding the crash), but may lead to harder-to-debug problems calling other stored procedures if you don't get the order and type of parameters exactly right. (Connector/NET can no longer map them for you using the metadata.)
2) Switch to a different ADO.NET MySQL library that doesn't have this bug: MySqlConnector on NuGet. It's highly compatible with Connector/NET, performs faster, and fixes a lot of known issues.
I found an answer with which I am quite pleased. It is changing the connection string by adding CheckParameters=false:
using (MySqlConnection conn = new MySqlConnection("Server=localhost;Database=Spike;uid=Spike;pwd=sample;CheckParameters=false"))
This disables parameter checking, and thereby information_schema queries.

C# ADO.Net to db2 iseries - connection not valid

I'm having problems connecting to a DB2 iSeries database from a C# ADO.Net program.
I can connect from the Windows box to the DB2/iSeries using the ClientAccess "Data Transfer From iSeries" tool, with these settings:
IBM i name: 192.168.0.1
User: VCT130
Passwd: pass
File name: CHGDG#VL/AREA(AREA)
and it retrieves 23 records.
I'm trying to access the same data from a simple C# program summarised below:
using IBM.Data.DB2.iSeries;
string conStr= "DataSource=192.168.0.1;UserID=VCT130;Password=pass;Naming=System;LibraryList=QIWS,CHGDG#VL,CHNNL#VL,CHVAT#VL;DefaultCollection=QIWS;" ;
string sql= "SELECT * from CHGDG#VL/Area;" ; // ALSO TRIED ...from CHGDG#VL/Area(AREA);
iDB2Connection conn = new iDB2Connection(conStr);
iDB2Command cmd = new iDB2Command(sql, conn);
iDB2DataReader rdr = cmd.ExecuteReader();
The conn and cmd objects get created OK, but the ExecuteReader() call fails with:
Unhandled Exception: System.InvalidOperationException: The operation cannot complete because the connection is not valid.
at IBM.Data.DB2.iSeries.iDB2Command.verifyConnection()
at IBM.Data.DB2.iSeries.iDB2Command.ExecuteDbDataReader(CommandBehavior behavior)
at IBM.Data.DB2.iSeries.iDB2Command.ExecuteReader()
at test04.DBDB2.read() in
c:\Users\mikeb\projs\ClassLibrary1\ClassLibrary1\DBDB2.cs:line 27
My line 27 is the call to cmd.ExecuteReader()
Any ideas please?
19 Nov Further thoughts:
[ Please excuse any clumsy etiquette, I'm a new poster here ]
Am I missing something? I'm thinking there are only 2 things to go
wrong here:
My code. No, too simple, and verified by #MikeWills' post
My connection string
Or could there be something else?
- re IBM.Data.DB2.iSeries.iDB2Command.verifyConnection()
Does someone here have access to the code to say what this method does, and what might be causing it to fail?
Solved. I was missing the following:
need to add conn.Open() after conn= new ....
Add CheckConnectionOnOpen=true; to connection string
Remove / from query string
See if this sample helps you out. I have written a library to make IBM server connections easier, this is a very old version of that library. I need to get the new version somewhere public again.
Update: My connection string is: DataSource=127.0.0.1;DefaultCollection=LIBRARY;Naming=sql;UserID=USER;Password=PASSWORD;

Categories