I'm a newbie in Visual Studio and I want to make a database system that allows the user to insert, update, delete and search data using a Windows Forms application.
I already watched 3 tutorial how but I'm getting the same error. when I delete my ExecuteNonQuery() call, it doesn't have any error but the data I entered into my textboxes is not inserted into my database. When I put it back I'm getting this kind of error
ERROR:
CODE:
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;
using System.Threading.Tasks;
namespace EaglePlannersDatabase
{
public partial class Form1 : Form
{
SqlConnection connection = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\Adrian\Documents\EaglePlannersDataBase.mdf;Integrated Security=True;Connect Timeout=30");
public Form1()
{
InitializeComponent();
}
private void InsertButton_Click(object sender, EventArgs e)
{
connection.Open();
SqlCommand cmd = new SqlCommand("Insert Into EAGLEPLANNERS(policy number,plan type,renewal date,name,age,address,birthday,email,home/office number,mode of payment,amount) values (#policy number,#plan type,#renewal date,#name,#age,#address,#birthday,#email,#home/office number,#mode of payment,#amount)", connection);
cmd.Parameters.AddWithValue("#policy number", int.Parse(policyNumbertxtbox.Text));
cmd.Parameters.AddWithValue("#plan type", planTypetxtbox.Text);
cmd.Parameters.AddWithValue("#renewal date", int.Parse(renewalDatetxtbox.Text));
cmd.Parameters.AddWithValue("#name", nametxtbox.Text);
cmd.Parameters.AddWithValue("#age", int.Parse(agetxtbox.Text));
cmd.Parameters.AddWithValue("#address", addresstxtbox.Text);
cmd.Parameters.AddWithValue("#birthday", int.Parse(birthdaytxtbox.Text));
cmd.Parameters.AddWithValue("#email", (emailtxtbox.Text));
cmd.Parameters.AddWithValue("#home/office number", int.Parse(homeofficetxtbox.Text));
cmd.Parameters.AddWithValue("#mode of payment", (modeofpaymenttxtbox.Text));
cmd.Parameters.AddWithValue("#amount", int.Parse(amounttxtbox.Text));
cmd.ExecuteNonQuery();
connection.Close();
policyNumbertxtbox.Text = "";
planTypetxtbox.Text = "";
renewalDatetxtbox.Text = "";
nametxtbox.Text = "";
agetxtbox.Text = "";
addresstxtbox.Text = "";
birthdaytxtbox.Text = "";
emailtxtbox.Text = "";
homeofficetxtbox.Text = "";
modeofpaymenttxtbox.Text = "";
amounttxtbox.Text = "";
MessageBox.Show("Record inserted successfully!");
}
}
}
As a newbie, getting the pieces working first, then applying to the user interface I would apply second. I will try to summarize each piece. First your connection itself looked strange as others have pointed out. I would try to first make sure the connection itself works before applying any attempt at sql insert/update/delete going on. So you might try
SqlConnection connection = new SqlConnection(
#"Data Source (LocalDB)\MSSQLLocalDB; AttachDbFilename=C:\Users\Adrian\Documents\EaglePlannersDataBase.mdf;
Integrated Security=True;
Connect Timeout=30" );
private void TestConnect()
{
if( connection.Open() )
// great, you have a good connection
connection.Close();
else
// message to yourself why a failed connection and fix it...
}
Once you know your connection is good, then on to your sql-insert. Having good column names is important. Dont try to be fancy with human readable with spaces types of column names, just causes headaches. Use simple and direct as others have pointed out in prior comments. Also, when parameterizing, I have tried to always slightly alter the insert/update/delete parameters with a "p" prefix indicating the PARAMETER FOR the column, such as
insert into SomeTable ( oneColumn, secondCol ) values ( #pOneColumn, #pSecondCol )
just to avoid bad confusion. If an error comes out via "oneColumn" vs "pOneColumn" in the message, you KNOW which thing is at fault. The column itself does not work, or the specific parameter/value being supplied.
Next, readability of your SQL statements, especially as they get longer. Use spaces and I typically use a leading "#" before the quoted sql command to allow for line continuations as I edited your previous answer. So the same above insert would be written more like
var cmd = new SqlCommand(
#"insert into SomeTable
( oneColumn,
secondCol
)
values
( #pOneColumn,
#pSecondCol
)", connection );
So if you ever needed to add additional columns (or remove), you can see the paired set of insert columns vs parameters much easier.
Now the testing. Don't try to work off some user-entered values, put in known VALID values so you dont have to worry about user entered values. Get the command to WORK, then pull values from interface later. (continuing from above sample)
cmd.Parameters.AddWithValue("#pOneColumn", 17 );
cmd.Parameters.AddWithValue("#pSecondCol", "some Text");
Then try to execute that and make sure IT works. Once it does, THEN start pulling from your user interface
cmd.Parameters.AddWithValue("#pOneColumn", int.Parse( yourTextControl.Text ));
cmd.Parameters.AddWithValue("#pSecondCol", anotherTextControl.Text );
Find your mistakes BEFORE you let any human interaction get into and screw-up the rest of what you think SHOULD work.
Note, if you make public properties to your view models such as
public int someAge {get; set;}
and then set the bindings of the data entry control in the screen to this someAge property, it will only allow a numeric entry to be entered and will otherwise have a value of zero if someone tries to put in text. Similarly if you are dealing with dates, and if date/time, always use datetime fields for querying purposes vs formatted date as a text field. You will thank yourself in the future when querying for things within date range periods. HTH
Finally,try to avoid using AddWithValue. Instead, properly identify the expected data type as described in the linked article. I just left original context to your code for testing and debug researching purposes.
This would be the possible answer on your question, what I have done here, first I changed your connection string by removing AttachDbFilename attribute, and replace that by adding of Initial Catalog attribute where I set the name of your database.
Next thing, I declared variables where the values from textboxes will be stored, these values of variables will be our parameters, this is not necessary to do, it is just my own style, you can keep as you done.
I have seen also, that you are not using try/catch/finally block and you are closing the connection in the same part of code where you opening the connection, and maybe that is the reason why your values are not being stored into the table, so I decided to round your code within that block. If you don't know what is try/catch/finally block you can read the documentation here . We are opening the connection and do all operations on database in try block, in catch block we are catching all errors that might be caused in our application and in finally we are closing the connection. You will also notice that I created additional check, where I checking the result of ExecuteNonQuery() method, and if result of ExecuteNonQuery method is equals to 1 - records is inserted successfully, otherwise it fails.
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;
using System.Threading.Tasks;
namespace EaglePlannersDatabase
{
public partial class Form1 : Form
{
SqlConnection connection = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;Initial Catalog=EaglePlannersDataBase;Integrated Security=True;Connect Timeout=30");
public Form1()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void InsertButton_Click(object sender, EventArgs e)
{
int policyNumber = Convert.ToInt32(policyNumbertxtbox.Text);
string planType = planTypetxtbox.Text;
int renewalDate = Convert.ToInt32(renewalDatetxtbox.Text);
string name = nametxtbox.Text;
int age = Convert.ToInt32(agetxtbox.Text);
string address = addresstxtbox.Text;
int birthday = Convert.ToInt32(birthdaytxtbox.Text);
string email = emailtxtbox.Text;
int homeOfficeNumber = Convert.ToInt32(homeofficetxtbox.Text);
string modeOfPayment = modeofpaymenttxtbox.Text;
int amount = Convert.ToInt32(amounttxtbox.Text);
try
{
connection.Open();
SqlCommand cmd = new SqlCommand("Insert Into tbl1 (PolicyNumber,planType,renewalDate,name,age,address,birthday,email,homeOfficeNumber,modeOfPayment,amount) values (#PolicyNumber,#planType,#renewalDate,#name,#age,#address,#birthday,#email,#homeOfficeNumber,#modeOfPayment,#amount)", connection);
cmd.Parameters.AddWithValue("#PolicyNumber",policyNumber);
cmd.Parameters.AddWithValue("#planType",planType);
cmd.Parameters.AddWithValue("#renewalDate",renewalDate);
cmd.Parameters.AddWithValue("#name",name);
cmd.Parameters.AddWithValue("#age",age);
cmd.Parameters.AddWithValue("#address",address);
cmd.Parameters.AddWithValue("#birthday",birthday);
cmd.Parameters.AddWithValue("#email",email);
cmd.Parameters.AddWithValue("#homeOfficeNumber",homeOfficeNumber);
cmd.Parameters.AddWithValue("#modeOfPayment",modeOfPayment);
cmd.Parameters.AddWithValue("#amount",amount);
int result = cmd.ExecuteNonQuery();
if(result == 1)
{
MessageBox.Show("Record Inserted Successfully!");
policyNumbertxtbox.Text = "";
planTypetxtbox.Text = "";
renewalDatetxtbox.Text = "";
nametxtbox.Text = "";
agetxtbox.Text = "";
addresstxtbox.Text = "";
birthdaytxtbox.Text = "";
emailtxtbox.Text = "";
homeofficetxtbox.Text = "";
modeofpaymenttxtbox.Text = "";
amounttxtbox.Text = "";
}
else
{
MessageBox.Show("Something went wrong!");
}
}
catch(SqlException ex)
{
MessageBox.Show("We have found error with operation on database: " + ex.Message);
}
catch(Exception ex)
{
MessageBox.Show("We have found error in your code: " + ex.Message);
}
finally
{
connection.Close();
}
}
}
}
here's my new code
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;
using System.Threading.Tasks;
namespace EaglePlannersDatabase
{
public partial class Form1 : Form
{
SqlConnection connection = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=C:\Users\Adrian\Documents\EaglePlannersDataBase.mdf;Integrated Security=True;Connect Timeout=30");
public Form1()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void InsertButton_Click(object sender, EventArgs e)
{
connection.Open();
SqlCommand cmd = new SqlCommand(
#"Insert Into tbl1
( PolicyNumber,
planType,
renewalDate,
name,
age,
address,
birthday,
email,
homeOfficeNumber,
modeOfPayment,
amount )
values
( #PolicyNumber,
#planType,
#renewalDate,
#name,
#age,
#address,
#birthday,
#email,
#homeOfficeNumber,
#modeOfPayment,
#amount )", connection);
cmd.Parameters.AddWithValue("#PolicyNumber", int.Parse(policyNumbertxtbox.Text));
cmd.Parameters.AddWithValue("#planType", planTypetxtbox.Text);
cmd.Parameters.AddWithValue("#renewalDate", int.Parse(renewalDatetxtbox.Text));
cmd.Parameters.AddWithValue("#name", nametxtbox.Text);
cmd.Parameters.AddWithValue("#age", int.Parse(agetxtbox.Text));
cmd.Parameters.AddWithValue("#address", addresstxtbox.Text);
cmd.Parameters.AddWithValue("#birthday", int.Parse(birthdaytxtbox.Text));
cmd.Parameters.AddWithValue("#email", (emailtxtbox.Text));
cmd.Parameters.AddWithValue("#homeOfficeNumber", int.Parse(homeofficetxtbox.Text));
cmd.Parameters.AddWithValue("#modeOfPayment", (modeofpaymenttxtbox.Text));
cmd.Parameters.AddWithValue("#amount", int.Parse(amounttxtbox.Text));
cmd.ExecuteNonQuery();
connection.Close();
policyNumbertxtbox.Text = "";
planTypetxtbox.Text = "";
renewalDatetxtbox.Text = "";
nametxtbox.Text = "";
agetxtbox.Text = "";
addresstxtbox.Text = "";
birthdaytxtbox.Text = "";
emailtxtbox.Text = "";
homeofficetxtbox.Text = "";
modeofpaymenttxtbox.Text = "";
amounttxtbox.Text = "";
MessageBox.Show("Record Inserted Successfully!");
}
}
}
here's my database
I'm new to coding in C# and have looked around but finding it hard to extrapolate an answer for my problem.
I'm currently just trying to get to grips with adding text and selected text from a combobox into a simple database table. However when I try to add the information I get an error of SqlException was unhandled. I've looked at other answers and saw it maybe something to do with adding a connection, which I've tried but it's still not working...
My code and error message as in the image link below but just in case here is my code also,
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.Data.SqlClient;
using System.Windows.Forms;
namespace SavetoDbTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
using (SqlConnection test = new SqlConnection("Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=C:\\Users\\User\\Documents\\Visual Studio 2015\\Projects\\SavetoDbTest\\SavetoDbTest\\Hobbie.mdf;Integrated Security=True"))
{
using (SqlCommand again = new SqlCommand())
{
again.CommandText = "INSERT INTO Table Values('" + textBox1.Text + "', '" + comboBox1.Text + "')";
again.Parameters.AddWithValue("#Name", textBox1.Text);
again.Parameters.AddWithValue("#Hobby", comboBox1.Text);
again.Connection = test;
test.Open();
again.ExecuteNonQuery();
test.Close();
MessageBox.Show("Data Entry Successful");
}
}
}
}
}
+1 for trying to use parameterized queries! But you're not doing it right :-)
again.CommandText = "INSERT INTO Table Values('" + textBox1.Text + "', '" + comboBox1.Text + "')";
again.Parameters.AddWithValue("#Name", textBox1.Text);
again.Parameters.AddWithValue("#Hobby", comboBox1.Text);
This add parameters when the query string doesn't expect them. Probably this is also the cause for the exception you're seeing.
Your query string must look like this:
again.CommandText = "INSERT INTO [Table] Values(#Name, #Hobby)";
Also, TABLE is a reserved word in SQL. So if your table is named Table, you should wrap it in square brackets.
Use this instead of:
private void button1_Click(object sender, EventArgs e)
{
using (SqlConnection test = new SqlConnection("Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=C:\\Users\\User\\Documents\\Visual Studio 2015\\Projects\\SavetoDbTest\\SavetoDbTest\\Hobbie.mdf;Integrated Security=True"))
{
using (SqlCommand again = new SqlCommand())
{
again.CommandText = "INSERT INTO [TableName] Values(#Name,#Hobby)";
again.Parameters.AddWithValue("#Name", textBox1.Text);
again.Parameters.AddWithValue("#Hobby", comboBox1.Text);
again.Connection = test;
test.Open();
again.ExecuteNonQuery();
test.Close();
MessageBox.Show("Data Entry Successful");
}
}
}
As mentioned by PaulF it is always a good practise to use Try..Catch block. It will give you the exception message if the code doesn't works for you. Here you go.
private void button1_Click(object sender, EventArgs e)
{
try
{
using (SqlConnection test = new SqlConnection("YourConnectionStringName"))
{
using (SqlCommand again = new SqlCommand())
{
again.CommandText = "INSERT INTO Table Values(#Name,#Hobby)";
again.Parameters.AddWithValue("#Name", textBox1.Text);
again.Parameters.AddWithValue("#Hobby", comboBox1.Text);
again.Connection = test;
test.Open();
again.ExecuteNonQuery();
test.Close();
MessageBox.Show("Data Entry Successful");
}
}
}
catch (Exception ex)
{
throw ex;
}
}
Check whether it is working or not. Hope atleast it will give you one step ahead result to let you know if any exception arises
Precisely this exception is being thrown because table is a reserved keyword. SQL engine encounters this reserved keyword, when it expects to find a proper name of the table and thus throws an exception. Try specifiying correct table name, because I believe this table name was given just as an example.
Your statement should look a little bit more like this
INSERT INTO MyTable Values ...
Other answers about using parametrized query in incorrect way are also valid.
there are 3 issues in your code.
1) you have reserved keyword for table name, Table
2) SQL query you are building from code is incorrect.
3) You need to specify your command type.
Solution: Change table name to something meaningful, like employeedata or testdata and modify your code according to given below.
again.CommandType = CommandType.Text;
again.CommandText = "INSERT INTO TestData(ColumnName1,ColumnName2) Values('" + textBox1.Text + "', '" + comboBox1.Text + "')";
again.Connection = test;
test.Open();
again.ExecuteNonQuery();
test.Close();
MessageBox.Show("Data Entry Successful");
I wrote program which selects and should delete a row from gridview based on the ID but it throws an exception that #ComplainantTypeID is not provided to the stored procedure but I checked in debugging, it sends and adds value but it still throws exception.
Code:
protected void btnDeletePopUp_Click(object sender, EventArgs e)
{
try
{
int ComplainantTypeID = Convert.ToInt32(txtSelectedID.Text.Trim());
ManageComplainantType mngComplainantType = new ManageComplainantType();
mngComplainantType.Delete(ComplainantTypeID);
Clear(txtName, txtSelectedID);
HiddenFieldSetMessage.Value = "Delete";
HiddenFieldShowMessage.Value = "True";
}
catch (Exception)
{
HiddenFieldSetMessage.Value = "NotDeleted";
HiddenFieldShowMessage.Value = "True";
}
}
Delete function in BLL:
public void Delete(int ComplainantTypeID)
{
SqlCommand cmd = new SqlCommand("DeleteComplainantTypes_SP", DataBaseConnection.OpenConnection());
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter pComplainantTypeID = new SqlParameter("#ComplainantTypeID", ComplainantTypeID);
cmd.Parameters.Add(pComplainantTypeID);
cmd.ExecuteNonQuery();
DataBaseConnection.CloseConnection();
}
Stored procedure:
PROCEDURE [dbo].[DeleteComplainantTypes_SP]
#ComplainantTypeID smallint
AS
BEGIN
BEGIN TRY
DELETE FROM ComplainantTypes WHERE ComplainantTypeID = #ComplainantTypeID
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE() AS ErrorMessage
END CATCH
END
Try
cmd.Parameters.AddWithValue("#ComplainantTypeID", value);
or
SqlParameter pComplainantTypeID = new SqlParameter("#ComplainantTypeID",SqlDbType.SmallInt,value);
You must show exception for better assistance, but the problem actually is in data type. You pass int but expected smallint. Look at the SQL Server Data Type Mappings article to choose appropriate data type.
UPDATE
You cant convert int to smallint you must pass parameter of type short which maps to smallint sql type.
Declare
public void Delete(short ComplainantTypeID)
instead of
public void Delete(int ComplainantTypeID)
and keep SP unchanged.
try this
sqlCommand.Parameters.Add("#ComplainantTypeID", SqlDbType.Int).Value = ComplainantTypeID;
I am having problems getting data to be displayed in a gridview in VS 2010.
I have a SQLdataSource which is connecting to my database but the gridview is not showing at all, my error message is all that is displayed. Would anyone know why this is?
This is the code that I have:
`using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Data;
using System.Configuration;
using System.Web.Services.Description;
namespace DBprototype2
{
public partial class _Default : System.Web.UI.Page
{
void Page_Load(Object sender, EventArgs e)
{
// This example uses Microsoft SQL Server and connects
// to the Northwind sample database. The data source needs
// to be bound to the GridView control only when the
// page is first loaded. Thereafter, the values are
// stored in view state.
if(!IsPostBack)
{
// Declare the query string.
String queryString =
"SELECT * FROM ";
// Run the query and bind the resulting DataSet
// to the GridView control.
DataSet ds = GetData(queryString);
if (ds.Tables.Count > 0)
{
GridView1.DataSource = ds;
GridView1.DataBind();
Label1.Text = "Connected.";
}
else
{
Label1.Text = "Unable to connect to the database.";
}
}
}
DataSet GetData(String queryString)
{
// Retrieve the connection string stored in the Web.config file.
String connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
DataSet ds = new DataSet();
try
{
// Connect to the database and run the query.
SqlConnection connection = new SqlConnection(connectionString);
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);
// Fill the DataSet.
adapter.Fill(ds);
Label1.Text = "Connected.";
}
catch(Exception ex)
{
// The connection failed. Display an error message.
Label1.Text = "Unable to connect.";
}
return ds;
}
}
}
`
If anyone could tell me the problem with my code that would be extremely helpful.
The problem is your query:
String queryString =
"SELECT * FROM ";
You are missing the table to select from, later in your method GetData you are not adding any table name in the query, that is why it is failing.
Also consider enclosing your connection in using statement
Use the Exception object ex.Message instead of hard coded error in label, this will help you debug and see what exactly is going wrong.
Not for this particular scenario but always consider using parametrized queries.
Hi i have a login which connects to a server string and executes this when the login button is pushed. It returns the invalid error if the user and password is not stored on the database but it throws a "Index was outside on the bounds of array" error if they are on the database. How would i fix this??
Thanks
My connection string is located in my appconfig file, could the problem be in there?
##########FORM WINDOWS AFTER LOGIN BUTTON CLICK
private void btnOK_Click(object sender, EventArgs e)
{
SqlConnection con = Program.GetConnection;
SqlDataReader dr = null;
try
{
SqlCommand cmd = new SqlCommand("SELECT * FROM Users WHERE UserName='" +
txtName.Text + "'AND Password='" + textpassword.Text + "'", con);
dr = cmd.ExecuteReader();
if (dr.Read())
{
Program.UserLoginName = dr.GetString(3);
this.Close();
}
else
MessageBox.Show("Invalid Username & Password!");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
#######PROGRAM.CS FILE
Using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Configuration;
namespace FrontEndV1
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Login());
}
public static SqlConnection GetConnection
{
get
{
string ConnectionString = ConfigurationManager.ConnectionStrings["FrontEndV1Connection"].ConnectionString;
SqlConnection con = new SqlConnection(ConnectionString);
con.Open();
return con;
}
}
public static string UserLoginName { get; set; }
}
}
I think that mistake lays here: dr.GetString(3); try to change 3 to 2. Numeration begins from 0 in arrays.
You don't say where the error is thrown, but I suspect this line:
Program.UserLoginName = dr.GetString(3);
Would throw the error if the query returns any fewer than 4 columns.
Also, this is vulnerable to Sql injection. Use a stored proc or parameterised query.
This is your problem:
Program.UserLoginName = dr.GetString(3);
You're getting a field whose index is greater than returned fields count.
You must use an index between 0 and dr.FieldCount-1.
Or you can use dr.GetString(dr.GetOrdinal(desired_field_name)): this is better (even if it needs more instructions) because you could swap returning order (maybe you need to change your query) without losing functionality.
i think you only have three columns. The index of the 3rd column is 2, so change this line
Program.UserLoginName = dr.GetString(3);
to
Program.UserLoginName = dr.GetString(2);.
Can you not debug the application? If you can do then try to locate from where the exception is being thrown. As suggested by Marco and other user if you notice exception when executing dr.GetString(3) then problem lies there. Try using correct column ordinal, or use SELECT Column1, Column2, ..., ColumnN FROM Table so that you know exactly which ordinal to specify.
Bad coding:
using select *, you should use the names of the columns
using indexes to retrieve values in a row, you should use the actual column name returned
If the above would have been applied there would be no problem.
I had The Same error using SQL Server Express 2014 with Login Stored Procedure from 3 different tables, I was really confused what was goin on, but finally found that I had more columns Selected from One Table then other two
sometimes its the logic behind it