I tried to create a CLR stored procedure in VS2017 but encountering error "NOT Connected." while executing that stored procedure.
I need to connect to other database server to grab some data. Therefore I cannot use context=true in SqlConnection.
Stored procedure will be created in serverA
This stored procedure will query data from serverB
Data will be stored back to serverA.
Is there anything I need to do in order to have regular connection in CLR stored procedure?
Please advise. Thanks!
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void udp_CLR_GetData()
{
string ConnStr = "server=MyServer; database=MyDB; user id=accabc; password=abc123";
string sql = " select top 1 ID from [dbo].Table1 ";
SqlDataReader dr = null;
DataTable dt = new DataTable();
try
{
using (SqlConnection fcon = new SqlConnection(ConnStr))
{
if (fcon.State == ConnectionState.Open)
{
SqlContext.Pipe.Send("Connected.");
using (SqlCommand fcmd = new SqlCommand(sql, fcon))
{
SqlContext.Pipe.Send("Before executing reader...");
dr = fcmd.ExecuteReader();
SqlContext.Pipe.Send("After executing reader...");
SqlContext.Pipe.Send("Before send...");
SqlContext.Pipe.Send(dr);
SqlContext.Pipe.Send("After send...");
}
}
else
{
SqlContext.Pipe.Send("NOT Connected.");
}
}
}
catch(Exception ex)
{
SqlContext.Pipe.Send("Exception error (udp_CLR_GetData): " + ex.Message);
}
finally
{
if(dr != null && !dr.IsClosed)
{
dr.Close();
}
}
}
}
Creating a new instance of a SqlConnection in:
using (SqlConnection fcon = new SqlConnection(ConnStr))
does not create it in an "open" state. You need to actually open it for it to be "open". So, I would remove the if (fcon.State == ConnectionState.Open) and the associated else part of it. I would also remove the SqlContext.Pipe.Send("Connected."); line.
Then, just before the dr = fcmd.ExecuteReader(); line, add a line for:
fcon.Open();
This way you open the connection and immediately execute the command. No need to open the connection only to do other work getting the command ready.
For more info on working with SQLCLR in general, please visit: SQLCLR Info
Try defining the data source in the connection string instead of server
string ConnStr = "DataSource=MyServer;Initial Catalog=MyDB;User Id=accabc;Password=abc123";
other than that, make sure clr is enabled on the server:
https://learn.microsoft.com/en-us/sql/relational-databases/clr-integration/clr-integration-enabling?view=sql-server-ver15
Related
I have a stored procedure in one of my Azure databases that links to external tables from another database.
If I run this stored procedure in the DB it runs fine, returning the data I expect. If I call the same stored procedure with the same input parameters from C# code, it is running, but returning null data at the points where the data is fetched from the external tables.
I have checked my user has permission to access the external tables...
Would anyone have any ideas what else I can check?
Thanks,
private void UpdateTABLEX(int ID)
{
string CSQuery = "EXEC [stg].[UpdateTableX_Proc] #ID";
using (SqlConnection cn = new SqlConnection(DB1))
{
try
{
cn.Open();
using (SqlCommand cmd = new SqlCommand(CSQuery, cn))
{
cmd.Parameters.AddWithValue("#ID", ID);
cmd.ExecuteNonQuery();
}
Refresh();
}
catch (Exception e)
{
Error error = new Error(e.ToString(), "TableX Issue");
error.LogError();
}
}
}
ok so the first problem is the connection string itself it has this exception that i do not understand so i tried to put it in a try catch syntax but as i inserted it in the public partial class Form1 : Form the parenthesis are acting up so i inserted it in a function and now the fuction has this error:
Severity Code Description Project File Line Suppression State
Error CS0161 'Form1.connection()': not all code paths return a value Restaurant Management System C:\Users\admin\source\repos\Restaurant Management System\Restaurant Management System\Form1.cs 36 Active
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.SqlClient;
namespace Restaurant_Management_System
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
panel1.BackColor = Color.FromArgb(50, Color.Black);
label1.BackColor = Color.FromArgb(30, Color.Beige);
label2.BackColor = Color.FromArgb(0, Color.Black);
Password.BackColor = Color.FromArgb(0, Color.Black);
}
SqlCommand cmd;
SqlDataReader dr;
public SqlConnection connection()
{
try
{
SqlConnection con = new SqlConnection("Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename= \"|Data Directory|\\Coffee(LoginEmployee).mdf\";Integrated Security=True;");
}
catch (Exception ex)
{
MessageBox.Show("Error message: COULD NOT CONNECT STRING: " + ex);
}
}
private string getUsername()
{
SqlConnection con = connection();
cmd = new SqlCommand("SELECT nalue FROM EmployeeLog where Property=Username", con);
dr = cmd.ExecuteReader();
dr.Read();
return dr[0].ToString();
}
private string getPassword()
{
SqlConnection con = connection();
cmd = new SqlCommand("SELECT nalue FROM EmployeeLog where Property=Password", con);
dr = cmd.ExecuteReader();
dr.Read();
return dr[0].ToString();
}
What do i need to replace? why does it not all return a value? if i use the void case it will also have this error that i cannot explicitly convert it to sqlconnection. this is made in the latest visual studio 2017
If you catch the exception, no SqlConnection will be returned. So you could return null after showing the message box.
Then of course, you will need to do a null check after calling connection() so you don't get a null reference exception trying to use it.
You also need to return the connection you are creating:
return new SqlConnection("Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=|Data Directory|Coffee(LoginEmployee).mdf;Integrated Security=True;");
Note: I don't recommend hard-coding your connection string either! You would normally add the connection string to your app.config/web.config and read it using ConfigurationManager.ConnectionStrings... - this is because you might have different instance names on different machines, or you might want to point to a database on a server rather than local. You will not need to change the code and recompile just to make it work on more than one machine.
There is information on microsoft's class library site (https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnectionstringbuilder.attachdbfilename(v=vs.110).aspx) saying: An error will be generated if a log file exists in the same directory as the data file and the 'database' keyword is used when attaching the primary data file. In this case, remove the log file. Once the database is attached, a new log file will be automatically generated based on the physical path.
Hi I'm having a problem finding the correct connection statement for my web-service to an sql-server database. I'm trying to retrieve data from my database to check a users login details.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
namespace BTC_Service
{
public class UseDatabase
{
SqlConnection sqlConn;
internal Boolean Connect()
{
try
{
sqlConn = new SqlConnection(#"Integrated Security=true; Initial Catalog=BTCFS_DataBase; Data Source=.\SQLEXPRESS;");
sqlConn.Open();
return true;
}
catch (SqlException ex)
{
return false;
}
}
internal void DisconnectDatabase()
{
sqlConn.Close();
}
internal Boolean ExecuteCommand(String query)
{
try
{
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = query;
cmd.ExecuteNonQuery();
return true;
}
catch (SqlException ex)
{
return false;
}
}
internal SqlDataReader ExecuteQuery(String query)
{
try
{
SqlCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = query;
return cmd.ExecuteReader();
}
catch (SqlException ex)
{
return null;
}
}
}
}
The database is created with sql-server 2008 and the path for it is:
C:\BTCFS_DataBase\db_BTDC_data.mdf
and the log file
C:\BTCFS_DataBase\db_BTDC_log.ldf
There is no password for the database and the code is as follows:
USE master
GO
create database db_BTCFC
ON PRIMARY
(
NAME = 'db_BTCFC_Data',
FILENAME = 'c:\BTCFS_DataBase\db_BTDC_data.mdf',
SIZE = 5MB,
FILEGROWTH = 10%
)
LOG ON
(
NAME = 'db_BTFC_log',
FILENAME = 'c:\BTCFS_DataBase\db_BTDC_log.ldf',
SIZE = 5MB,
FILEGROWTH = 10%
)
GO
Is there any suggestion to what I am doing wrong?
Should I add the database to visual studio in a specific way?
Or am i creating my database in the wrong way?
Thank you in advance.
The fact that you are connected using Integrated Security, means that your local user account on Windows should be authenticated on the SQL server instance which is hosted locally on your machine (evident by the "." in the Data Source, which refers to your local machine). It might be that the setup of your SQL server instance doesn't accommodate windows authentication. Check that your configuration allows for "mixed mode" authentication, i.e. either Windows authentication or username/password authentication...
I found this statement to be more effective than the previous one:
sqlConn = new SqlConnection(#"Integrated Security=SSPI; Initial Catalog=BTCFS_DataBase; Data Source=localhost");
Thanks #Wolfish for the link.
I want to write a MySql statement that will connect to the database, select a column from the table, then output that data to a text file to a specific location on my computer. I have searched the internet for a couple days now and don't seem to find the answer I am looking for. I am fairly new to c#, MySql, and Visual Studio. I am just trying to learn how to write the correct statements and get the desired result. Any help would be greatly appreciated.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
using MySql.Data;
using System.Windows.Forms;
using System.IO;
namespace NewPractice
{
public class Connect
{
static void Main()
{
string results = #"server=111.111.11.111; userid=anyone;
password=anypassword; database=anydatabase";
MySqlConnection conn = null;
try
{
conn = new MySqlConnection(results);
conn.Open();
//Console.WriteLine(
File.WriteAllLines(
#"C:\Documents and Settings\anyone\My Documents\Tests\testoutput.txt",
results.ToArray());
}
catch (MySqlException ex)
{
Console.WriteLine("Error: (0)", ex.ToString());
}
finally
{
if (conn != null)
{
conn.Close();
}
}
}
}
}
You're writing the contents of the result string to the file, not the data you're attempting to select. You need to run a sql command and get a SqlDataReader object to write your data to the file.
string results = #"server=111.111.11.111; userid=anyone;
password=anypassword; database=anydatabase";
MySqlConnection connection = new MySqlConnection(results);
MySqlCommand command = connection.CreateCommand();
MySqlDataReader reader;
command.CommandText = "select * from mycustomers";
connection.Open();
reader = command.ExecuteReader();
using(var sw = new StreamWriter("C:\MyPath\MyFile.txt"))
{
while (reader.Read())
{
var row = (IDataRecord)reader;
sw.WriteLine(row["myColumn"]);
}
}
connection.Close();
If the database is on your local machine you can use 'select .. into outfile'. http://dev.mysql.com/doc/refman/5.1/en/select-into.html. This will write to a folder on the server so it's not v useful if it's a different machine and you can't copy from there.
There are plenty of tutorials out there for accessing MySQL from .NET.
This is one: http://zetcode.com/db/mysqlcsharptutorial/
In any language, there are a few simple steps to read from a database:
1. connect to the database.
2. execute a query
3. iterate through the results of the query
4. close the connection.
What you are doing in your code is connecting to the database and then trying to write the connection information to a file.
I am using SMO in C# to run an SQL script. I need to output the results of the file into a text file.
When using a command line to run the query I can get the desired result using the "-o [output file]" argument. Is there a way to carry out the same operation using an SMO object?
At the moment my code simply sends an sql script to a server:
// Read the sql file
string script = sqlFile.OpenText().ReadToEnd();
// Create a new sql connection, and parse this into a server connection.
SqlConnection sqlConnection = new SqlConnection(connectionString);
Server server = new Server(new ServerConnection(sqlConnection));
// Run the sql command.
server.ConnectionContext.ExecuteNonQuery(script);
Any help would be much appreciated!
I don't know if you can do the exact same thing, but assuming that the script returns some data you could just execute the script, read the returned data and store it to a file, for example:
using (StreamWriter sw = new StreamWriter("output.txt"))
{
using(SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using(SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = script;
using(SqlDataReader rdr = cmd.ExecuteReader())
{
while(rdr.Read())
{
sw.WriteLine(rdr.Item("colName").ToString();
}
}
}
}
}
Discovered that the SQL script that I needed to execute basically only outputted errors it encountered into the output file. I was able to catch this using:
catch (Exception ex)
{
executedSuccessfully = false;
SqlException sqlex = ex.InnerException as SqlException;
if (sqlex != null)
{
exceptionText = sqlex.Message;
}
}
Thanks for your help though Ho! I may need this in the future...