I was already able to fetch data from SAP by calling a RFC into Excel Workbook using VBA.
But now I like to do the same in an Excel AddIn (VSTO) with c#.
There are little informatoin about this.
The microsoft.data.sapclient does not work really:
https://msdn.microsoft.com/en-us/library/cc185499(v=bts.10).aspx
I first recogniced that the RFC Exec command must be changed (token expected: Execute Function..). So I'm wondering if this documentation is old or something else changed? (Also explained in this question here: C# SapDataReader cmd.ExecuteReader() Error)
After this change I'm executing a simple RFC which updates a table - no import/export parameters, no tables
Even just executing this simple RFC ends in "No results available for the given query command"
Does anybody out there have solved this issue? Anyone has a proper working example?
My code is at the moment the following for the button on the custom task pane:
using System;
using System.Collections.Generic;
//using System.ComponentModel;
//using System.Drawing;
//using System.Data;
//using System.Linq;
using System.Text;
//using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.Data.SapClient;
namespace SupplierEvaluation
{
public partial class CTP_Uster_SupplierEvaluation : UserControl
{
public CTP_Uster_SupplierEvaluation()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string connstr = "ASHOST=Hostname; SYSNR=sysnr; CLIENT=client; LANG=EN; USER=username; PASSWD=password;";
using (SapConnection conn = new SapConnection(connstr))
{
conn.Open();
using (SapCommand cmd = (SapCommand)conn.CreateCommand())
{
cmd.CommandText = "EXECUTE Function ZTEST_RHE ";
using (SapDataReader dr = (SapDataReader)cmd.ExecuteReader())
{
}
conn.Close();
}
}
}
}
You can try using SQL Server Profiler to trace all calls made to the SQL Server, It will require priviliges on the server, impact server performance and you need to filter out your calls amongst all other calls.
Related
I am trying to create a project that will read, write,and check for duplicates in my access data base file. I am using C# and keep getting "Connection failed error that I have written into the program if the connection state = 0. If anyone can offer any help I would appreciate it. I am using Access 2016 and I am not sure what references I need for my project (if any). Everything I have found online is either outdated or doesn't work.
Thank you!
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Net;
using System.IO;
using System.Data.OleDb;
namespace RHG
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
using (OleDbConnection connection = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.16.0;Data Source=C:\Users\grosales\Documents\rhg\RHG\Used.accdb"))
{
try
{
connection.Open();
MessageBox.Show("connected");
}
catch (Exception ex)
{
MessageBox.Show("connection failed");
}
}
}
`
You have not opened the connection.
connection.Open();
Note: Checking the connection state is not enough. You might get an exception when trying to open the connection. Enclose it in try-catch instead.
It is also a good practice to enclose work on a connection with using
using (var connection = new OleDbConnection()) {
connection.ConnectionString =
#"Provider=Microsoft.ACE.OLEDB.16.0;Data Source=C:\Users\...\Used.accdb";
try {
connection.Open();
//TODO: do something with the connection
} catch (Exception ex) {
MessageBox.Show("Connection Failed\r\n\r\n" + ex.Message);
}
}
This ensures that the connection will be closed and the resources be released.
Try following the examples here: https://msdn.microsoft.com/en-us/library/system.data.oledb.oledbconnection(v=vs.110).aspx
You're missing the connection.Open(); statement, which should be wrapped in a try catch.
Additionally, you can specify the connection string within the constructor, like
using (OleDbConnection connection = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.16.0;Data Source=C:\Users\grosales\Documents\rhg\RHG\Used.accdb"))
{
//do DB access here
}
//no need to call connection.Close() - it's automatically done once you leave the using block.
All I want to do is to retrieve data from tables in .accdb file.
Here is my full application:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.OleDb;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
OleDbConnection myConn = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:/Microland.accdb;Persist Security Info=False;");
myConn.Open();
OleDbCommand myQuery = new OleDbCommand("select CustID from Customers WHERE CustID = 1;", myConn);
OleDbDataReader myReader = myQuery.ExecuteReader();
if(myReader.HasRows)
{
myReader.Read();
label1.Text = myReader.ToString();
}
myConn.Close();
}
}
}
I think I am missing some using at the very top or my code is somewhat broken becasue then I click the button1 the label1 text changes to System.Data.OleDb.OleDbDataReader.
Also is this the correct way to connect to access data base (.accdb) Do I need to do this walkthrough in order for it to work or this is irrelevant to what I need to do?
Thanks for any information! Very appreciated
When you call myReader.ToString() it returns a string that represents the current object. So "System.Data.OleDb.OleDbDataReader" is exactly that.
It seems like you want the label to be equal to the data that's read. I'm not familiar with this reader in particular, but refer here for documentation.
You'll need to call one of the Get*() functions.
label1.Text = myReader["CustID"] as string; // if nullable field
Or
label1.Text = (string)myReader["CustID"] // if not null
I have run into a problem where my C# code is creating a whole new database instead of using a preexisting one. Then my program runs into errors where the program cannot find the table to insert the information even though the preexisting database has the table because the code itself is looking at the new table. Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Finisar.SQLite;
namespace WestSlope
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
SQLiteConnection sqlite_conn;
SQLiteCommand sqlite_cmd;
//SQLiteDataAdapter sqlite_datareader;
sqlite_conn = new SQLiteConnection("DataSource=ClientLogDB.db;Version=3;New=True;Compress=True;");
//open conection
sqlite_conn.Open();
//create sql commands
sqlite_cmd = sqlite_conn.CreateCommand();
//Let SQLite command know query is known
sqlite_cmd.CommandText = "INSERT INTO ASAM (ASAMone, ASAMtwo, ASAMthree, ASAMfour, ASAMLim, ASAMLimEX) VALUES ('Had to call', 'Reffered', 'Had to call', 'Watched', 1 , 'Injured legs');"
;
//execute query
sqlite_cmd.ExecuteNonQuery();
sqlite_conn.Close();
}
}
}
What the code is supposed to do is when the user presses a button the program will save information to the preexisting database; but, as you can see the program is making a new database instead of using the preexisting one.
Use new=false in your connection string to use existing database file.
Following should be the connection string:
sqlite_conn = new SQLiteConnection("DataSource=ClientLogDB.db;Version=3;New=False;Compress=True;");
I have installed the MySQL server using XAMMP.Created a new database with some data using phpmyadmin.Then i tried to connect to database using this code.But it did not connect.It shows me an error.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
namespace TestConsole
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Testing!");
SqlConnection myco = new SqlConnection("server=localhost;User Id=root;database=customer;Trusted_Connection=yes");
try
{
myco.Open();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.ReadKey();
}
}
}
Error:
http://pastebin.com/MyEtk4w6
You have MySql then you need to use the classes for MySql not the ones used for SqlServer
MySqlConnection myco = new MySqlConnection("Server=localhost;Database=customer;" +
"Uid=username;Pwd=password;");
Also the connection string for MySql is different
Server=localhost;Database=customer;Uid=username;Pwd=password;
The connection strings for MySql could be very numerous, you should check the correct one for your requirement here at connectionstrings.com
It's because you're using a SqlConnection object which is for Microsoft SQL Server.
Use a MySQLConnection instead.
I'm extremely new to C# and programming anything except for SQL. I've gotten the below code to happen on a Form and on a button click. If I wanted to just make this run on open, how would I do that? I'm very new to C# as you can tell (just started today learning it but its pretty exciting!)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Oracle.DataAccess.Client; // ODP.NET Oracle managed provider
using Oracle.DataAccess.Types;
namespace OraTrigger
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string oradb = "Data Source=OMP1;User Id=user;Password=pass;";
OracleConnection conn = new OracleConnection(oradb); // C#
conn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT cast(Count(*) as varchar(20)) as trig FROM ZDMSN.TRIGGER_TEST";
//cmd.CommandType = CommandType.Text;
OracleDataReader dr = cmd.ExecuteReader();
dr.Read();
int cnt;
if (int.TryParse(dr.GetString(0), out cnt))
{
if (cnt > 0)
{
System.Diagnostics.Process.Start(#"C:\testfile.bat");
}
}
cmd.CommandText = "TRUNCATE TABLE ZDMSN.TRIGGER_TEST";
conn.Dispose();
}
}
}
If you need to run your code as a scheduled task then a command line application is more suitable.
Just create a new project and select Console Application.
Then move all of your button click code inside the Main method written for you by the Visual Studio IDE.
Rembember to set the references to the Oracle ODP.NET library and import the relevant using statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Oracle.DataAccess.Client; // ODP.NET Oracle managed provider
using Oracle.DataAccess.Types;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string oradb = "Data Source=OMP1;User Id=user;Password=pass;";
using(OracleConnection conn = new OracleConnection(oradb))
using(OracleCommand cmd = new OracleCommand("SELECT Count(*) as trig FROM ZDMSN.TRIGGER_TEST", conn))
{
conn.Open();
int cnt = (int)cmd.ExecuteScalar();
if (cnt > 0)
{
System.Diagnostics.Process.Start(#"C:\testfile.bat");
cmd.CommandText = "TRUNCATE TABLE ZDMSN.TRIGGER_TEST";
cmd.ExecuteNonQuery();
}
}
}
}
}
I have also revised your code to get a single value from the database. For this case is enough to use the Command.ExecuteScalar method that returns the first column of the first row obtained from your sql command text. Because the count(*) should Always return a single row you could easily cast the return value of ExecuteScalar to your record count variable.
EDIT I have added the logic to TRUNCATE the table involved. Please pay attention that you should use the code provided here. Your code will probably fail because you have an open DataReader and when a DataReader is open you cannot execute other commands (This is true for SqlServer without Multiple Active Result Sets enabled, I really don't know if this rules applies also to the Oracle NET Provider)
Subscribe to Shown or Load event of form and move your code to that event handler.
Form.Shown Event Occurs whenever the form is first displayed.
Form.Load Event Occurs before a form is displayed for the first time.
Also I suggest to extract your code to some Data Access related class, or at least to separate method. And call that method from event handler.