My code:
private void txtSearch_TextChanged(object sender, EventArgs e)
{
if (txtSearch.Text == "")
{
DGViewListItems.Rows.Clear();
populateTable();
}
else
{
if (byItemcode.Checked == true)
{
DGViewListItems.Rows.Clear();
using (SqlConnection con = db.Connect())
{
try
{
//these Messageboxes is just for testing. to test if the data is correct
MessageBox.Show('%' + STEntry.whseFr.Text.Trim() + '%');
MessageBox.Show('%' + txtSearch.Text.Trim() + '%');
SqlDataReader rd;
SqlCommand cmd = new SqlCommand("sp_WhseItemsList", db.Connect());
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#Action", "I");
switch (activeform.formname)
{
case "Issuance List":
//cmd.Parameters.AddWithValue("#WHSE", STEntry.whseFr.Text);
break;
case "Stocks Transfer List":
cmd.Parameters.AddWithValue("#WHSE", STEntry.whseFr.Text.Trim());
break;
case "Stocks Adjustment List":
cmd.Parameters.AddWithValue("#WHSE", SADJEntry.txtWhse.Text.Trim());
break;
}
cmd.Parameters.AddWithValue("#Desc", "");
cmd.Parameters.AddWithValue("#Itemcode", '%' + txtSearch.Text.Trim() + '%');
rd = cmd.ExecuteReader();
int i = 0;
if (rd.HasRows)
{
while (rd.Read())
{
DGViewListItems.Rows.Add();
DGViewListItems.Rows[i].Cells["itemcode"].Value = rd["itemcode"].ToString();
DGViewListItems.Rows[i].Cells["whsecode"].Value = rd["whsecode"].ToString();
DGViewListItems.Rows[i].Cells["description"].Value = rd["description"].ToString();
DGViewListItems.Rows[i].Cells["uom"].Value = rd["uom"].ToString();
DGViewListItems.Rows[i].Cells["quantity"].Value = rd["quantity"].ToString();
i++;
}
}
}
catch (Exception ex)
{
}
}
}
else if (byDescription.Checked == true)
{
}
}
}
This is not working for me, because it does not populate the dgv correctly. I don't think the query is the problem inside the stored procedure, because I tried the query manually and its working fine
The query I tried:
SELECT DISTINCT A.*, B.description, B.uom
FROM inventoryTable A
LEFT OUTER JOIN Items B
ON A.itemcode = B.itemcode WHERE (A.whsecode = 'WHSE1' AND A.itemcode LIKE '%S%');
The output:
And here is the output for the code in the textchanged event:
Here is more example output:
This is the stored procedure content for reference:
ALTER PROCEDURE [dbo].[sp_WhseItemsList]
#Action char(5) = '',
#WHSE char(15) = '',
#Desc varchar(50) = '',
#Itemcode char(15) = ''
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF #Action = 'A'
BEGIN
SELECT DISTINCT A.*, B.description, B.uom
FROM inventoryTable A
LEFT OUTER JOIN Items B
ON A.itemcode = B.itemcode WHERE A.whsecode = #WHSE;
END
IF #Action = 'I'
BEGIN
SELECT DISTINCT A.*, B.description, B.uom
FROM inventoryTable A
LEFT OUTER JOIN Items B
ON A.itemcode = B.itemcode WHERE (A.whsecode = #WHSE) AND (A.itemcode LIKE #Itemcode);
END
IF #Action = 'D'
BEGIN
SELECT DISTINCT A.*, B.description, B.uom
FROM inventoryTable A
LEFT OUTER JOIN Items B
ON A.itemcode = B.itemcode WHERE (A.whsecode = #WHSE) AND (B.description LIKE #Desc);
END
END
Your #Itemcode is a char(15), which means it always has 15 positions. So this becomes:
A.itemcode LIKE '%S% ').
And LIKE does not ignore trailing spaces, like an = would do. So it only matches a value that contains "S" and ends in 12 spaces.
Related
I stay with that error when I'm trying to format a date in my code:
Cmd.CommandText = #"
DECLARE #command varchar(5000);
DECLARE #RestoreList TABLE(DB_name VARCHAR(100), RS_name VARCHAR(100), RS_DateFinExercice DATE, RS_IsClosed VARCHAR(50));
SELECT #command = 'IF ''?'' IN (SELECT name FROM sys.databases WHERE HAS_DBACCESS(name) = 1 AND CASE WHEN state_desc = ''ONLINE'' THEN OBJECT_ID( QUOTENAME( name ) + ''.[dbo].[P_DOSSIER]'',''U'' ) END IS NOT NULL) BEGIN USE [?] SELECT DB_name = CAST(DB_NAME() AS VARCHAR(100)), RS_name = CAST(a.D_RaisonSoc AS VARCHAR(100)), RS_DateFinExercice = CAST((SELECT Max(v) FROM (VALUES (a.[D_FinExo01]), (a.[D_FinExo02]), (a.[D_FinExo03]),(a.[D_FinExo04]),(a.[D_FinExo05])) AS value(v)) AS DATE), RS_IsClosed = CAST((SELECT CASE WHEN (SUM (CASE WHEN JM_Cloture !=2 THEN 1 ELSE 0 END)>0) THEN '''' ELSE ''arc'' END FROM F_JMOUV) AS VARCHAR(50)) FROM [dbo].[P_DOSSIER] a INNER JOIN F_JMOUV b ON DB_name() = DB_NAME() GROUP BY D_RaisonSoc, D_FinExo01, D_FinExo02, D_FinExo03, D_FinExo04, D_FinExo05 HAVING COUNT(*) > 1 END'
INSERT INTO #RestoreList EXEC sp_MSforeachdb #command;
SELECT * FROM #RestoreList ORDER BY DB_name;";
SqlDataReader dr = Cmd.ExecuteReader();
List<DBtoRestore> dgUIDcollection = new List<DBtoRestore>();
if (dr.HasRows)
{
while (dr.Read())
{
DBtoRestore currentdgUID = new DBtoRestore
{
CUID_dbname = dr["DB_name"].ToString(),
CUID_RaisonSoc = dr["RS_name"].ToString(),
CUID_DateFinExercice = dr["RS_DateFinExercice"].ToString(),
CUID_IsClosed = dr["RS_IsClosed"].ToString()
};
dgUIDcollection.Add(currentdgUID);
}
}
dgDBtoRestore.ItemsSource = dgUIDcollection;
Cnx.Close();
The problem is on this line of code:
CUID_DateFinExercice = dr["RS_DateFinExercice"].ToString()
For now, my datagrid report date like 01/01/2020 00:00:00. In SQL, I have 01-01-2020 style.
I want to have the same style in my datagrid.
I have try something like ToString("dd-MM-yyyy") but it's in that context I've received the error.
Any idea to help me?
Convert to a DateTime and then call ToString on it:
Convert.ToDateTime(dr["RS_DateFinExercice"]).ToString("dd-MM-yyyy")
Solution :
CUID_DateFinExercice = ((DateTime)dr["RS_DateFinExercice"]).ToString("dd-MM-yyyy"),
What I am trying to do here is:
Display ALL Employees (in the datagridview)
Display Employees that HAVE health insurance records (in the datagridview)
Display Employees WITHOUT health insurance records(in the datagridview)
I can now display all of my employees to the datagridview(dgvEmp) with this stored procedure:
IF #action_type = 'DisplayAllEmployees'
BEGIN
SELECT e.employee_id, e.employee_name, e.city, e.department, e.gender,
h.health_insurance_provider, h.plan_name, h.monthly_fee, h.insurance_start_date
FROM dbo.Employee e
LEFT JOIN dbo.EmployeeHealthInsuranace h ON h.employee_id = e.employee_id
END
and this function (in my winforms):
private void FetchEmpDetails( string readType ) {
//Load/Read Data from database
using ( SqlConnection con = new SqlConnection( connectionStringConfig ) )
using ( SqlCommand sqlCmd = new SqlCommand( "spCRUD_Operations", con ) ) {
try {
con.Open();
DataTable dt = new DataTable();
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.Parameters.AddWithValue( "#action_type", readType );
sqlCmd.Connection = con;
SqlDataAdapter sqlSda = new SqlDataAdapter( sqlCmd );
sqlSda.Fill( dt );
dgvEmp.AutoGenerateColumns = false;//if true displays all the records in the database
dgvEmp.Columns[ 0 ].DataPropertyName = "employee_id";
dgvEmp.Columns[ 1 ].DataPropertyName = "employee_name";
dgvEmp.Columns[ 2 ].DataPropertyName = "city";
dgvEmp.Columns[ 3 ].DataPropertyName = "department";
dgvEmp.Columns[ 4 ].DataPropertyName = "gender";
dgvEmp.Columns[ 5 ].DataPropertyName = "health_insurance_provider";
dgvEmp.Columns[ 6 ].DataPropertyName = "plan_name";
dgvEmp.Columns[ 7 ].DataPropertyName = "monthly_fee";
dgvEmp.Columns[ 8 ].DataPropertyName = "insurance_start_date";
dgvEmp.Columns[ 8 ].DefaultCellStyle.Format = "MMMM dd, yyyy";
dgvEmp.DataSource = dt;
} catch ( Exception ex ) {
MessageBox.Show( "Error: " + ex.Message );
}
}
}
I can display all by calling the function: FetchEmpDetails( "DisplayAllEmployees" );
But, when I try to display Employees that HAVE health insurance records or display Employees WITHOUT health insurance records (with the function call through winforms), I can't get them to display at the dataGridView. THE DATA GRID VIEW IS JUST BLANK.
This is the Stored Procedure:
ELSE IF #action_type = 'WithHealthInsuranceRecords'
BEGIN
SELECT e.employee_id, e.employee_name, e.city, e.department, e.gender,
h.health_insurance_provider, h.plan_name, h.monthly_fee, h.insurance_start_date
FROM dbo.Employee e
INNER JOIN dbo.EmployeeHealthInsuranace h ON h.employee_id = e.employee_id
WHERE h.monthly_fee > 0
END
ELSE IF #action_type = 'WithoutHealthInsuranceRecords'
BEGIN
SELECT e.employee_id, e.employee_name, e.city, e.department, e.gender,
h.health_insurance_provider, h.plan_name, h.monthly_fee, h.insurance_start_date
FROM dbo.Employee e
LEFT JOIN dbo.EmployeeHealthInsuranace h ON h.employee_id = e.employee_id
WHERE h.monthly_fee = 0
END
But, If I run this as "New Query" in my server explorer, the expected output shows up:
EDIT: Thanks to everyone who commented and posted an answer, those are very helpful and I appreciate it.
When I was taking a break I found the problem, my action_type parameter was #action_type NVARCHAR(25), then I realized that the string that I passed there was > 25. I now changed it to #action_type NVARCHAR(100) and it now displays well!
Your query is wrong:
WHERE h.monthly_fee = 0
This will filter the table to rows that are not null, which basically means you are doing an INNER JOIN not a LEFT.
Instead, you can either change it to:
WHERE h.monthly_fee IS NULL;
Or better, use a NOT EXISTS query:
SELECT e.employee_id, e.employee_name, e.city, e.department, e.gender,
h.health_insurance_provider, h.plan_name, h.monthly_fee, h.insurance_start_date
FROM dbo.Employee e
WHERE NOT EXISTS (SELECT 1
FROM dbo.EmployeeHealthInsuranace h
WHERE h.employee_id = e.employee_id);
I have a quite large SQL query that works as expected when i´m exceuting it in MS SQL. However when I run it from C# it does not fetch any rows (dataTable does not return any rows). If I instead use a simple query, for e.g. "SELECT * Accounts FROM TableX" from C#, dataTable returns all the rows it should do. I also tried to remove all the spaces from the SQL query so everything was on the same line, but without any change. Here is the code:
internal void GetData()
{
try
{
using (SqlConnection connection = new SqlConnection(connectionBuilder.ToString())) //1. Open connection
{
connection.Open();
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(GetSqlString(), connection))
{
DataTable dataTable = new DataTable();
dataAdapter.Fill(dataTable);
foreach (DataRow dataRow in dataTable.Rows)
{
var field1 = dataRow[0];
var field2 = dataRow[1];
Logger.Log(field1 + " " + field2);
}
}
}
}
catch (Exception ex)
{
utilityProvider.Log("Error" + ex.ToString());
}
}
private string GetSqlString()
{
return #"SELECT
Field1 = subscr.cind_recipient,
Field2 = COALESCE(
a.name, s.cind_name,
CASE WHEN c.cind_is_protected_identity = 0 THEN c.fullname
ELSE ISNULL(c.cind_protected_firstname, '') + ' ' + ISNULL(c.cind_protected_lastname, '') END ),
Field3 = COALESCE(CASE WHEN c.cind_is_protected_identity <> 1 THEN c.address1_line3
ELSE c.cind_protected_address1_line3 END,
s.cind_postal_line3),
Field4 = COALESCE(CASE WHEN c.cind_is_protected_identity = 0 THEN c.address1_line1
ELSE c.cind_protected_address1_line1 END,
a.address2_line1, s.cind_postal_line1),
Field5 = COALESCE(CASE WHEN c.cind_is_protected_identity = 0 THEN c.address1_line2
ELSE c.cind_protected_address1_line2 END,
a.address2_line2, s.cind_postal_line2),
Field6 = COALESCE(CASE WHEN c.cind_is_protected_identity = 0 THEN mpc1.cind_postalcode
ELSE mpc.cind_postalcode END,
a.address1_postalcode, s.cind_postal_postalcode),
Field7 = COALESCE(CASE WHEN c.cind_is_protected_identity = 0 THEN mpc1.cind_city
ELSE mpc.cind_city END,
a.address1_city, s.cind_postal_city),
Field8 = c.cind_member_number,
Field9 = ISNULL(COALESCE(c.cind_union_section_idname, a.cind_mml_mub_union_section_idname), a1.cind_mml_mub_union_section_idname),
Field10 = CASE WHEN c.cind_is_protected_identity <> 1 THEN c.cind_soc_sec_no
ELSE c.cind_protected_cind_soc_sec_no END,
Field11 = COALESCE(a.cind_organization_no, s.cind_organization_no),
Field12 = c.gendercodename,
Field13 = cind_count,
Field14 = k1.cind_name,
Field15 = k1.cind_number,
Field16 = k2.cind_name,
Field17 = k2.cind_number,
Field18 = 'sam',
Field19 = subscr.villa_free_exname
FROM dbo.Filteredcind_mml_mub_subscription subscr
INNER JOIN Filteredcind_mml_mub_service svc
ON subscr.cind_mml_mub_service_id = svc.cind_mml_mub_serviceid
AND svc.cind_code = 'PE002'
LEFT JOIN Filteredcind_mml_mub_site s
ON subscr.cind_mml_mub_site_id = s.cind_mml_mub_siteid
LEFT JOIN FilteredAccount a
ON subscr.cind_account_id = a.accountid
LEFT JOIN FilteredAccount a1
ON a1.accountid = s.cind_account_id
INNER JOIN FilteredContact c
ON subscr.cind_contact_id = c.contactid
AND c.statecode = 0
LEFT JOIN Filteredcind_mml_mub_postalcity mpc
ON c.cind_protected_cind_postalcity_id = mpc.cind_mml_mub_postalcityid
LEFT JOIN Filteredcind_mml_mub_postalcity mpc1
ON c.cind_postalcity_id = mpc1.cind_mml_mub_postalcityid
LEFT JOIN Filteredcind_mml_mub_county lan
ON c.cind_county_id = lan.cind_mml_mub_countyid
LEFT JOIN Filteredcind_mml_mub_country land
ON lan.cind_country_id = land.cind_mml_mub_countryid
LEFT JOIN (Filteredcind_mml_mub_membership m1
INNER JOIN (SELECT mt1.cind_mml_mub_membership_typeid
FROM Filteredcind_mml_mub_membership_type mt1
WHERE mt1.cind_code = 'PRDI-45') mtt1
ON mtt1.cind_mml_mub_membership_typeid = m1.cind_mml_mub_membership_type_id)
ON c.contactid = m1.cind_contact_id
AND (m1.statuscode = 1
OR m1.statuscode = 434578)
AND m1.statecode = 0
LEFT JOIN Filteredcind_mml_mub_local_union k1
ON m1.cind_mml_mub_local_union_id = k1.cind_mml_mub_local_unionid
LEFT JOIN (Filteredcind_mml_mub_membership m2
INNER JOIN (SELECT mt2.cind_mml_mub_membership_typeid
FROM Filteredcind_mml_mub_membership_type mt2
WHERE mt2.cind_code = 'EXTR-01') mtt2
ON mtt2.cind_mml_mub_membership_typeid = m2.cind_mml_mub_membership_type_id)
ON c.contactid = m2.cind_contact_id
AND (m2.statuscode = 1
OR m2.statuscode = 126670001)
AND m2.statecode = 0
LEFT JOIN Filteredcind_mml_mub_local_union k2
ON m2.cind_mml_mub_local_union_id = k2.cind_mml_mub_local_unionid
WHERE subscr.statuscode = 1
AND subscr.statecode = 0";
}
If SELECT * works then its likely to be a timeout issue. However you should be receiving an exception.
The default timeout is 30 seconds.
How long does it take your query to run in MSSQL?
change the timeout by setting
cmd.Timeout = 300; // Change the number of seconds.
Alternatively improve the efficiency of your query.
Reduce your SQL line by line then you'll find the problem. Start with dropping all column, use * instead (as CathalMF said), then drop the joins, one by one.
I have a list with two columns in it: ID; int, Score: Double.
In addition, I have a table in SQL SERVER with several columns.One of them is id:int.
I want to have a query like below:
select * from tbl where id = id s in my list.
My codes are below:
protected void btnfind_Click(object sender, EventArgs e)
{
List<KeyValuePair<int, double>> candidatelist = CalculateScores();
FinalMatch(candidatelist);
BindGrid(cmd2);//Contains codes for filling grid view with cmd2 , sql data reader
}
protected void FinalMatch(List<KeyValuePair<int, double>> finallist)
{
DataTable tvp = new DataTable();
tvp = ConvertToDatatable(finallist);
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.CommandText = "dbo.DoSomethingWithCandidates";
SqlParameter tvparam = cmd2.Parameters.AddWithValue("#List", tvp);
tvparam.SqlDbType = SqlDbType.Structured;
cmd2.Connection = ClsDataBase.con;
}
protected DataTable ConvertToDatatable(List<KeyValuePair<int, double>> finallist)
{
DataTable dt = new DataTable();
dt.Columns.Add("ID");
dt.Columns.Add("Score");
foreach (var item in finallist)
{
var row = dt.NewRow();
row["ID"] = item.Key;
row["Score"] = item.Value;
dt.Rows.Add(row);
}
return dt;
}
protected void BindGrid(SqlCommand cmd)
{
if (ClsDataBase.con.State == ConnectionState.Closed)
ClsDataBase.con.Open();
SqlDataReader dr1 = cmd.ExecuteReader();
try
{
if (dr1.HasRows)
{
gv_allresults.DataSource = dr1;
gv_allresults.DataBind();
}
else
{
Response.Write("<script LANGUAGE='JavaScript' >alert('No Match')</script>");
}
if (dr1.IsClosed == false) dr1.Close();
}
catch (SqlException ex)
{
Response.Write("<script language='javascript'>alert(\"" + ex.ToString() + "\")</script>");
}
catch (Exception ex)
{
Response.Write("<script language='javascript'>alert(\"" + ex.ToString() + "\")</script>");
}
finally
{
ClsDataBase.con.Close();
}
}
And my codes in SQL server are:
CREATE TYPE dbo.CandidateList
AS TABLE
(
ID INT,
Score FLOAT
);
GO
CREATE PROCEDURE dbo.DoSomethingWithCandidates
#List AS dbo.CandidateList READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT ID FROM #List;
END
GO
I don't get the result. My procedure's codes are not complete. I don`t know what to do. Please help me.
Thanks so much.
Edited codes according to given suggestion:
protected void FinalMatch(List<KeyValuePair<int, double>> finallist)
{
int[] canArr = finallist.Select(x => x.Key).ToArray();
string csv = string.Join(",", canArr);
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.CommandText = "dbo.ReturnCandidates";
cmd2.Parameters.AddWithValue("#LIST", csv);
cmd2.Connection = ClsDataBase.con;
}
And new codes in Sql server are:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[CSVToTable] (#InStr VARCHAR(MAX))
RETURNS #TempTab TABLE
(id int not null)
AS
BEGIN
;-- Ensure input ends with comma
SET #InStr = REPLACE(#InStr + ',', ',,', ',')
DECLARE #SP INT
DECLARE #VALUE VARCHAR(1000)
WHILE PATINDEX('%,%', #INSTR ) <> 0
BEGIN
SELECT #SP = PATINDEX('%,%',#INSTR)
SELECT #VALUE = LEFT(#INSTR , #SP - 1)
SELECT #INSTR = STUFF(#INSTR, 1, #SP, '')
INSERT INTO #TempTab(id) VALUES (#VALUE)
END
RETURN
END
GO
CREATE PROCEDURE dbo.ReturnCandidates
(
#LIST VARCHAR(200)
)
AS
BEGIN
SELECT *
FROM tblspecifications
WHERE id IN ( SELECT * FROM dbo.CSVToTable(#LIST) )
END
I get this error: "Procedure or function ReturnCandidates has too many arguments specified",
In below line:
SqlDataReader dr1 = cmd.ExecuteReader();
Please help me. Thanks a lot
I see cmd2.ExecuteNonQuery() missing.
Also, why not make a comma separated list of ID's and then send it to the SQL function. Example
int[] canArr= candidatelist.Select(x => x.Key).ToArray();
string csv = string.Join(",", canArr);
EDIT:
I created a SQL Fiddle for your query. It works.
http://sqlfiddle.com/#!6/c3d013/1/1
How to update the full row if BatchNumber (in my case) exists?
In my table batch number is unique and I need to update the entire row or the quantity column if Batchnumber is exist
Please, help me to do this in a proper way
{
var conn = new SqlConnection(GetConnectionString());
var StrBuilder = new StringBuilder(string.Empty);
var splitItems = (string[])null;
foreach (string item in SC_PurLinr)
{
const string sqlStatement = "INSERT INTO DEL_Stores (DealerCode, Code, Qty, ExpireDate, BatchNumber) VALUES";
if (item.Contains(","))
{
splitItems = item.Split(",".ToCharArray());
StrBuilder.AppendFormat("{0}('{1}','{2}','{3}','{4}','{5}'); ", sqlStatement, splitItems[0], splitItems[1], splitItems[2], splitItems[3], splitItems[4]);
}
}
try
{
conn.Open();
SqlCommand cmd = new SqlCommand(StrBuilder.ToString(), conn) { CommandType = CommandType.Text };
cmd.ExecuteNonQuery();
wucMessagePopup1.showPopup(1, string.Empty, "Record Saved Successfully.");
}
catch (SqlException ex)
{
}
finally
{
conn.Close();
}
}
Use MERGE from SQL Server 2008:
WITH new_rows (
SELECT #value value
,#BatchNumber BatchNumber)
MERGE DEL_Stores target
USING new_rows source ON source.BatchNumber = target.BatchNumber
WHEN MATCHED THEN
UPDATE SET value = #value
WHEN NOT MATCHED THEN
INSERT (
BatchNumber
,value)
VALUES(
source.BatchNumber
source.value);
You can achieve this by stored procedure in better way.
Your procedure should be like this.
create PROCEDURE usp_Namae
#parmeter INT
,#parmeter INT
,#BatchNumber INT
AS
BEGIN
IF NOT EXISTS (
SELECT *
FROM tblname
WHERE BatchNumber = #BatchNumber
)
BEGIN
--INSERT query
END
ELSE
BEGIN
--Update query
END
END
Just add IF statement before insert data as below:
IF EXISTS (select * from sys.columns where object_id = OBJECT_ID(N'DEL_Stores') and name='BatchNumber')
BEGIN
// Do insert here
END