Porting MSSQL Application to Sybase (ASE 15.0), and experiencing a problem when I call GetDeleteCommand.
The error reported is:
Dynamic SQL generation for the DeleteCommand is not supported against
a SelectCommand that does not return any key column information.
The problem only occurs for temporary table, identical non-temporary table works fine.
Table contains a primary key.
Reproduced using test program below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using System.Data;
namespace DataAdapterTempTable
{
class Program
{
static void Main(string[] args)
{
String ConnectionString = "Provider=ASEOLEDB;Data Source=devsun3:5003;Initial Catalog=ctc;User ID=aigtac12;Password=aigtac12;"; // sybase connection string
//String ConnectionString = "Provider=SQLOLEDB;Data Source=fiji;Persist Security Info=False;Initial Catalog=nxgn0811;Integrated Security=SSPI"; // mssql connection string
String TableName = "#alex_temporary_table_test"; // does not work for sybase
//String TableName = "alex_real_table_test"; // works for sybase + mssql
String CreateStatement = "create table " + TableName + " (currency_id varchar(4) primary key, rate decimal(25,6), format char(1))";
String SelectStatement = "select * from " + TableName;
try
{
OleDbConnection con = null;
con = new OleDbConnection(ConnectionString);
con.Open();
OleDbCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = CreateStatement;
int count = cmd.ExecuteNonQuery();
OleDbCommand cm1 = con.CreateCommand();
cm1.CommandType = CommandType.Text;
cm1.CommandText = SelectStatement;
OleDbDataAdapter DA2 = new OleDbDataAdapter(cm1);
DataTable DT2 = new DataTable();
DA2.FillSchema(DT2, SchemaType.Mapped);
OleDbCommandBuilder cmdbldr = new OleDbCommandBuilder(DA2);
DA2.InsertCommand = cmdbldr.GetInsertCommand();
DA2.DeleteCommand = cmdbldr.GetDeleteCommand(); // this line fails in sybase for temporary table
DA2.UpdateCommand = cmdbldr.GetUpdateCommand();
DA2.Fill(DT2);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}
In the select statement, instead of * use the column names.
Contacted Sybase support, turns out I had to update some system stored procedures. There is a folder that ends with "oledb\sp", and I had to run a .bat file from the folder. I got the latest ebf and ran the batch file install_oledb_sprocs.bat, the problem went away. Worth mentioning, that sybase 15.5 did not have the issue without patching.
P.S. Thank you to 'aF' for your time looking into the issue.
Related
I would like to write a utility using VS2017 Data-Tools that would extract an Azure Sql database and create the dacpac on local file storage.
I understand I can use the SQL Server Object Explorer and extract from their but I want to write a c# executable that would do the same thing for me so I can automate it and schedule it to happen weekly.
I need to be able to exclude a few tables but other than that its a straight forward extract. Is this possible and is there an example I can use to get started with? Sorry this is all new to me so not sure where to begin.
found a solution that works for me:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.SqlClient;
using Microsoft.SqlServer.Dac;
private static string excludeSchemas = ConfigurationManager.AppSettings["ExcludeSchemas"];
private static string excludeTables = ConfigurationManager.AppSettings["ExcludeTables"];
private static string TableQuery = "SELECT SCHEMA_NAME(schema_id), name FROM sys.tables where SCHEMA_NAME(schema_id) not in ({0} ) and name not in ({1}) order by schema_id,name";
static void Main(string[] args)
{
Extract();
}
private static void Extract()
{
var sourceConnectionString = ConfigurationManager.AppSettings["SourceDbConnection"];
DacServices svc = new DacServices(sourceConnectionString);
DacExtractOptions dacExtractOptions = new DacExtractOptions
{
ExtractApplicationScopedObjectsOnly = true,
ExtractReferencedServerScopedElements = false,
VerifyExtraction = false,
Storage = DacSchemaModelStorageType.Memory
};
var tables = BuildTables();
var dacPacDest = ConfigurationManager.AppSettings["DacPacDestination"];
var sourceDb = ConfigurationManager.AppSettings["sourceDbName"];
svc.Extract(dacPacDest,sourceDb, "Sample DACPAC", new Version(1, 0, 0), "Sample Extract", tables, dacExtractOptions);
}
private static IEnumerable<Tuple<string, string>> BuildTables()
{
var tbls = new List<Tuple<string, string>>();
var tblConnection = ConfigurationManager.AppSettings["SourceDbConnection"];
using (SqlConnection connection = new SqlConnection(tblConnection))
{
connection.Open();
string query = string.Format(TableQuery, excludeSchemas, excludeTables);
using (SqlCommand command = new SqlCommand(query, connection))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
tbls.Add(new Tuple<string, string>(reader.GetString(0), reader.GetString(1)));
}
}
}
}
return tbls;
}
My application in WPF allows user to save some data from text boxes into Excel file (using OLEDB connection). I wish to add feature that every time new row is saved into Excel file a sequence number is added into EventID column in that Excel file.
But I'm getting an error while running the application related to parameter #EventId saying: 'parameter has no default value'.
I expect I have written wrong sql1 command to generate the serial number.
I'd appreciate your help.
private void btnSaveNewEvent1_Click_1(object sender, RoutedEventArgs e)
{
object eventName = txtEventName.Text;
object typeValue = txtEventType.Text;
object nameValue = txtAttributeName.Text;
object attribvValue = txtAValue.Text;
object descValue = txtEventDescrip.Text;
System.Data.OleDb.OleDbConnection MyConnection;
System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand();
System.Data.OleDb.OleDbCommand myCommand1 = new System.Data.OleDb.OleDbCommand();
String sql = null;
String sql1 = null;
MyConnection = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source='excel_file\\events2.xlsx'; " +
"Extended Properties=\"Excel 12.0 Xml;HDR=YES;\"");
try
{
//SQL STATEMENT TO SAVE INSERTED BY THE USER VALUES FROM THE TEXT BOXES
//SQL1 STATEMENT TO GENERATE EVENTID NUMBER EACH TIME THE USER SAVES NEW ROW OF DATA
MyConnection.Open();
myCommand.Connection = MyConnection;
sql = "Insert into [events$] (EventID,EventName, Type, Name, [Value], Description) values(#EventID,#EventName,#Type,#Name,#Val,#Desc)";
myCommand.CommandText = sql;
myCommand.Parameters.AddWithValue("#EventID",sql1);
myCommand.Parameters.AddWithValue("#EventName", eventName ?? DBNull.Value);
myCommand.Parameters.AddWithValue("#Type", typeValue ?? DBNull.Value);
myCommand.Parameters.AddWithValue("#Name", nameValue ?? DBNull.Value);
myCommand.Parameters.AddWithValue("#Val", attribvValue ?? DBNull.Value);
myCommand.Parameters.AddWithValue("#Desc", descValue ?? DBNull.Value);
myCommand1.Connection = MyConnection;
sql1= "DECLARE #i int = 0 while #i < EventID BEGIN SET #i = EventID + 1 END";
myCommand1.CommandText = sql1;
myCommand.ExecuteNonQuery();
myCommand1.ExecuteNonQuery();
MyConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
finally
{
MyConnection.Close();
Events eventsWindow = new Events();
eventsWindow.dgData.Items.Refresh();
}
}
Since your command is running before command1 sql1 = null, That is what your problem is.
You need to set the value of sql1 before executing the command. If you really want the value to be null you need to use DBNull.Value as you have for the other parameters.
I created a simple console application to test the ability to push data from an excel file into a dataset and it works fine on my local machine (win 8.1). However, when I move the project to server 2012, and run it, it always returns an empty dataset. I'm a little suspicious their is a local policy the account needs, however the account is a local admin.
class Class1
{
public DataSet ReturnExcelDataTable(string fileName)
{
DataSet dsImport = new DataSet();
DataSet ds = new DataSet();
string strConn;
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=" + fileName +
";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";";
try
{
OleDbDataAdapter cmd = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", strConn);
cmd.Fill(dsImport);
}
catch (Exception ex)
{
}
return dsImport;
}
}
static void Main(string[] args)
{
Class1 xls = new Class1();
string fileName = #"c:\temp\targets\test3.xlsx";
DataSet dt = xls.ReturnExcelDataTable(fileName);
foreach (DataRow dr in dt.Tables[0].Rows)
{
Console.WriteLine(dr[0]);
Console.ReadKey();
}
}
string connectionString = ConfigurationManager.ConnectionStrings["myConnection"].ConnectionString;
const string query = "my Select query here";
List<long> myList = new List<long>();
using (SqlConnection con = new SqlConnection(connectionString))
{
con.Open();
using (SqlCommand selectCommand = new SqlCommand(query, con))
{
selectCommand.CommandType = CommandType.Text;
SqlDataReader sqlreader = selectCommand.ExecuteReader();
while (sqlreader.Read())
{
long Id = (long)sqlreader["Id"];
List.Add(Convert.ToInt32(sqlreader[0].ToString()));
using (SqlCommand insertCommand = new SqlCommand("dbo.SP_Data", con))
{
insertCommand.CommandType = CommandType.StoredProcedure;
insertCommand.Parameters.Add("#Id", SqlDbType.BigInt).Value = Id;
insertCommand.Parameters.Add("#StatusId", SqlDbType.BigInt).Value = 1;
insertCommand.Parameters.Add("#ReportDate", SqlDbType.DateTime).Value = DateTime.Now;
insertCommand.Parameters.Add("#CreatedDate", SqlDbType.DateTime).Value = DateTime.Now;
insertCommand.Parameters.Add("#CreatedBy", SqlDbType.UniqueIdentifier).Value = DefaultUser();
insertCommand.ExecuteNonQuery();
}
}
}
}
I am getting the error "There is already an open DataReader associated with this Command which must be closed first." at the last line [insertCommand.ExecuteNonQuery();
You need to enalbe MARS in your connection string (MARS = Multiple Active Result Sets)
In short, this particular flag, when enabled in the connection string, allows to use the same connection used by the SqlDataReader also for executing commands. Otherwise, as stated by MSDN the connection is busy serving the SqlDataReader and cannot execute other commands.
Before Sql Server 2005 the developpers were forced to create, open and use another connection. (Still possible if your environment doesn't allow to change the connection string)
More info about MARS could be found on this MSDN article
Examples of connection string that uses MARS
I am working on a windows application in c#.net where I need to import an excel sheet into an Access database by the use of code in c#. I found the following code on the net and tried to use :
string path = #"D:\project_excel";
OleDbConnection con;
System.Data.DataTable dt = null;
//Connection string for oledb
string conn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + path + "; Extended Properties=Excel 8.0;";
con = new OleDbConnection(conn);
try
{
con.Open();
dt = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
String[] excelsheets = new String[dt.Rows.Count];
int i = 0;
foreach (DataRow dr in dt.Rows)
{
excelsheets[i] = dr["TABLE_NAME"].ToString();
i++;
}
// here i manaually give the sheet number in the string array
DataSet ds = new DataSet();
foreach (string temp in excelsheets)
{
// Query to get the data for the excel sheet
//temp is the sheet name
string query = "select * from [" + temp + "]";
OleDbDataAdapter adp = new OleDbDataAdapter(query, con);
adp.Fill(ds, temp);//fill the excel sheet data into a dataset ds
}
}
catch (Exception ex)
{
}
finally
{
con.Close();
}
However it gives an exception which is mentioned below :
The Microsoft Jet database engine cannot open the file 'D:\project_excel'. It is already opened exclusively by another user, or you need permission to view its data.
Further I don't know the meaning of Extended Properties. I am using Microsoft Office 2007 package.If I set Extended Properties = 7.0 it gives following error :
Could not find installable ISAM.
Please help by providing some code sample.
Thanks in advance..
Check to see if the connection string is correct for your Access database version.
For details Visit ConnectionString.com
by
Mohamed Inshafudeen J.
For the error : Could not find installable ISAM.
1: save your excel file as "Excel 97-2003 wrokbook "
2: and also include the reference "Microsoft.Office.Interop.Excel"
best of luck!