XML to String from Database call - MVC - c#

I'm trying to recycle an approach found here
to call a stored procedure from SQL Server, receive an XML response, render the response to a string variable, and process it against an XLST template. I can't seem to get the string variable created correctly. Here's what I'm doing in my controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.SqlClient;
using System.Configuration;
using Demo2.Models;
namespace Demo2.Controllers
{
public class CfsController : Controller
{
// GET: Cfs
public ActionResult Report()
{
{
SqlConnection con = new SqlConnection("data source=.; database=Test; integrated security=SSPI");
SqlCommand cmd = new SqlCommand("EXEC [TEST].[REPORTSERV].[CFSREPORT] #CFSNUMBER = N'010101-10';", con);
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
string response = rdr.ToString();
con.Close();
ViewBag.CurrentReport = response;
return View();
}
}
}
}
When I run the code I'm getting an error in the transform step in the tranformObj.Transform(reader, args, writer) step of the helper CS.
I believe the issue is caused by the string response variable not taking the XML response from the SQL Server as a string.

Since my stored procedure is going to return only one record (an XML response), I've changed ExecuteReader to ExecuteScalar and converted the response into a string. It's now working but it looks like some of the XML files I'm getting back are exceeding the size of the string variable.
string rdr = cmd.ExecuteScalar().ToString();
ViewBag.CurrentReport = rdr;

You never provided your SP source code... So it is assumed that it returns an XML data type.
You need to change the following two lines:
SqlDataReader rdr = cmd.ExecuteReader();
string response = rdr.ToString();
To the following:
using (XmlReader reader = cmd.ExecuteXmlReader())
{
XDocument xdoc = XDocument.Load(reader);
string response = xdoc.ToString();
}

Related

CLR Stored Procedure Unable to connect with SqlConnection Regular Connection

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

how to solve exception for the connection string(local database c#)

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.

How to use SQL Datareader and a foreach loop for Groupings of IDs? C#

I have a table which has the results of student's marks for particular modules (classes).
I take the mark percentage and multiply it against a value from the assessment table (based on the assessment ID). This part all works fine.
I tried to write a loop using the SQL data reader, to add up all the values FOR EACH MODULE. However, I can only seem to add up all the values altogether for a particular user (it's in the where clause). I can't put the moduleID = 1 in the WHERE clause because I need to see all results at once.
Here's the code I've already attempted, which adds up all the values for the user.
//set-up object to use the web.config file
string connectionString = WebConfigurationManager.ConnectionStrings["QSISConnection"].ConnectionString;
//set-up connection object called 'myConnection'
SqlConnection myConnection = new SqlConnection(connectionString);
// open database communication
myConnection.Open();
// create the SQL statement
string query = "SELECT ModuleAssessmentUser.ModuleID, ModuleAssessmentUser.AssessmentID, MarkPercentage * Assessment.AssessmentWeighting AS FinalMark FROM ModuleAssessmentUser INNER JOIN[Assessment] ON(Assessment.AssessmentID = ModuleAssessmentUser.AssessmentID) WHERE (ModuleAssessmentUser.UserID = 2)";
// set-up SQL command and use the SQL and myConnection object
SqlCommand myCommand = new SqlCommand(query, myConnection);
// create a SqlDataReader object that asks for data from a table
SqlDataReader rdr = myCommand.ExecuteReader();
// create variable to add column values
int totalmark = 0;
// when in read mode ask for data
while (rdr.Read())
{
// put variable value from moduleID column in local variable
string usermodule = rdr["ModuleID"].ToString();
// needs to be a text control called 'moduleid' on the aspx web page
modulenumber.Text = usermodule.ToString();
// get value of your weighting
int fmark = Convert.ToInt32(rdr["FinalMark"]);
// update the moduleweighting variable by adding the value in the column FinalMark
// this is in a loop so should accumulate the values
totalmark = totalmark + fmark;
result.Text = totalmark.ToString();
}
// once the adding up has been added up display total in final text box
// create a text control on aspx called 'result'
// need to convert int to string to display in text control
myConnection.Close();
I am still quite new to C# and ASP.NET, so any advice is appreciated.
Thanks in advance
Try code below :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace WindowsFormsApplication12
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//set-up object to use the web.config file
string connectionString = WebConfigurationManager.ConnectionStrings["QSISConnection"].ConnectionString;
//set-up connection object called 'myConnection'
SqlConnection myConnection = new SqlConnection(connectionString);
// open database communication
myConnection.Open();
//create the SQL statement
string query = "SELECT ModuleAssessmentUser.ModuleID, ModuleAssessmentUser.AssessmentID, MarkPercentage * Assessment.AssessmentWeighting AS FinalMark FROM ModuleAssessmentUser INNER JOIN[Assessment] ON(Assessment.AssessmentID = ModuleAssessmentUser.AssessmentID) WHERE (ModuleAssessmentUser.UserID = 2)";
//set-up SQL command and use the SQL and myConnection object
SqlCommand myCommand = new SqlCommand(query, myConnection);
//create a sqldatareader object that asks for dats from a table
SqlDataAdapter adapter = new SqlDataAdapter(myCommand);
DataTable dt = new DataTable();
adapter.Fill(dt);
dataGridView1.DataSource = dt;
int markPercentage = dt.AsEnumerable().Sum(x => x.Field<int>("MarkPercentage"));
}
}
}

Adding Data to Database but get a breakpoint everytime a function is called

I am trying to write myself a Music record database program.
It works perfectly untill I try using a form to add data using input from textboxes and a button.
It generates a break point and the following error
An Unhandled exception of type 'System.ArgumentException' Occured in
System.Data.dll
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 Musicrecord
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
--> using(var connection = new SqlConnection("connectionString"))**
{
connection.Open();
var sql = "INSERT INTO Table(Artist, Album, Release Year) VALUES(#Artist, #Album, #Release year)";
using(var cmd = new SqlCommand(sql, connection))
{
cmd.Parameters.AddWithValue("#Artist", textBox1.Text);
cmd.Parameters.AddWithValue("#Album", textBox2.Text);
cmd.Parameters.AddWithValue("#Release Year ", textBox3.Text);
cmd.ExecuteNonQuery();
}
I haven't found after several hours of googling a solution.
If connectionString is a local variable, you need to use it as;
using(var connection = new SqlConnection(connectionString))
not
using(var connection = new SqlConnection("connectionString"))
If you use it as "connectionString", SqlConnection expects it is a valid connection string. But it is not.
Also, if your column name more than one word, you need to use it with square brackets like [Release Year]. It is the same as it's paramter name.
And don't use AddWithValue. It may generate unexpected results. Use .Add() method or it's overloads.
using(var connection = new SqlConnection(connectionString))
using(var cmd = connection.CreateCommand())
{
cmd.CommandText = "INSERT INTO Table(Artist, Album, [Release Year]) VALUES(#Artist, #Album, #ReleaseYear)";
cmd.Parameters.Add(#Artist, SqlDbType.NVarChar).Value = textBox1.Text;
cmd.Parameters.Add(#Album, SqlDbType.NVarChar).Value = textBox2.Text;
cmd.Parameters.Add(#ReleaseYear, SqlDbType.NVarChar).Value = textBox3.Text;
connection.Open();
cmd.ExecuteNonQuery();
}
I assumed your all data types are NVarChar. Also it is a good practice to specify size value as a third parameter in .Add() method.

How do I create a MySql database connection that returns results to a text file?

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.

Categories