convert stamp to varchar and use it in c# - c#

guys i created stored procedure to synchronize my data in a table from the main database to the branches using C# service using a last stamp. in the stored procedure i converted the stamp of the main database to varchar select #CurrentStamp = convert(varchar, value) from parameter where id = 3 this stamp i should get it in the C# as an output and send it as parameter to the stored procedure in the branch save the data that should i synchronize then save this stamp in a parameter table as varchar. all by testing without using the soap service. when i tried to use it in the soap service it throws an exception hexadecimal value 0x00, is an invalid character . any help please i tried to convert it to varbinary but it keep changing the stamp to another value. if any one knows how to let the XML read this values without exception please help.
FamilyService.FamilyService fs = new FamilyService.FamilyService();
DataSet ds = fs.GetFamilyToSynchronize(Current.LoggedUserSchool.ID, stamp, out currentStamp);
-
public static DataSet GetFamilyToSynchronize(int schoolID, string stamp, out string CurrentStamp)
{
DataTable dtFamilyToSynchronize = new DataTable();
DataTable dtFamilyPhones = new DataTable();
CurrentStamp = "";
DataSet ds = new DataSet();
try
{
using (DataBaseClass db = new DataBaseClass())
{
db.Connect();
SqlCommand command = db.CreateCommand();
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetFamilyToSynchronize";
command.Parameters.AddWithValue("#SchoolID", schoolID);
command.Parameters.AddWithValue("#Stamp", stamp);
command.Parameters.AddWithValue("#CurrentStamp", CurrentStamp);
command.Parameters["#CurrentStamp"].Direction = ParameterDirection.InputOutput;
command.Parameters["#CurrentStamp"].Size = 255;
SqlDataAdapter da = new SqlDataAdapter(command);
da.Fill(ds);
CurrentStamp = command.Parameters["#CurrentStamp"].Value.ToString();
}
}
catch (Exception ex){Logger.LogException(ex);}
return ds;
}
SQL Stored Procedure
GO
ALTER Proc [dbo].[GetFamilyToSynchronize] (#SchoolID int , #Stamp varchar(255) = null, #CurrentStamp varchar(255) output) as
select #CurrentStamp = convert(varchar, value) from parameter where id = 3
SELECT f.*
into #tmpFamily
FROM [Family] f
inner join fatherschools fs on fs.FamilyID = f.ID
where f.id =f.fatherlinkid --not in (select FatherLinkID from family )
and schoolID = #SchoolID
and (#Stamp is null or f.stamp> convert(timestamp, isnull(#Stamp,'')))
select distinct f.id, phonetypeid,phonenumber, t.FatherLinkID
from familyphones f
inner join #tmpFamily t on t.ID = f.FamilyID
select * from #tmpFamily

Related

C# & SQL Server : parse Excel range into data table but data table returning as empty

I am trying to save values from an excel range to a data table. I am then parsing my data table into a stored procedure to save into the database.
System.Data.DataTable dt = new System.Data.DataTable();
dt.Columns.Add("Territory", typeof(string));
dt.Columns.Add("OptionID", typeof(string));
dt.Columns.Add("ProductClass", typeof(string));
dt.Columns.Add("Taken", typeof(string));
for (var idx = 7; idx < lastUsedRow; idx++)
{
string Territory = territory;
string optionID = ((string)Worksheet.Range["B" + idx].Value2);
string ProductClass = ((string)Worksheet.Range["C" + idx].Value2);
string Taken = ((string)Worksheet.Range["V" + idx].Value2);
}
dt.Rows.Add(optionID, Territory, ProductClass, Taken) //this is an issue it returns dt{}
SQL:
var connectionstring2 = ConfigurationManager.ConnectionStrings["SDYConString"].ConnectionString;
var cn2 = new SqlConnection(connectionstring2);
cn2.Open();
var cmd2 = new SqlCommand("dbo.sp_ui_sm_insertrows", cn2);
SqlParameter tvparam = cmd2.Parameters.AddWithValue("#dt", dt);
var da2 = new SqlDataAdapter(cmd2);
cmd2.CommandType = CommandType.StoredProcedure;
cmd2.ExecuteNonQuery();
cn2.Close();
SQL:
CREATE PROCEDURE [dbo].[sp_ui_sm_insertrows]
#dt AS tbl_type_lines READONLY
AS
BEGIN
INSERT INTO dbo.tbl_newline (TERRITORY, OPTION_ID, PRODUCT_CLASS, TAKEN)
SELECT
TERRITORY, OPTION_ID, PRODUCT_CLASS, TAKEN
FROM #dt;
END
I get this error:
Cannot insert the value NULL into column 'OPTION_ID', table '#dt'; column does not allow nulls. INSERT fails. The data for table-valued parameter "#dt" doesn't conform to the table type of the parameter.
SQL Server error is: 515, state: 2 The statement has been terminated.
The dt {} seems to be empty so it doesn't insert anything in it. When I go into debug mode there is a value in option ID variable - is this the correct way to insert the rows into the datatable? I need to map the created columns and rows together then parse into my stored procedure.

Issues in insert function in SQL Server and C#

C#:
protected void btnsearch_Click(object sender, EventArgs e)
{
SqlConnection con = Connection.DBconnection(); {
SqlCommand com = new SqlCommand("sp_studentresult", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.AddWithValue("#id", textstudentid.Text);
com.Parameters.AddWithValue("#id_student", textstudentid.Text.Trim());
SqlParameter retval = new SqlParameter("#output", SqlDbType.VarChar, 50);
com.Parameters.AddWithValue("#tamil", txttamil.Text.Trim());
com.Parameters.AddWithValue("#english", txtenglish.Text.Trim());
com.Parameters.AddWithValue("#maths", txtmaths.Text.Trim());
com.Parameters.AddWithValue("#science", txtscience.Text.Trim());
com.Parameters.AddWithValue("#socialScience", txtsocialscience.Text.Trim());
retval.Direction = ParameterDirection.Output;
com.Parameters.Add(retval);
com.ExecuteNonQuery();
string Output = retval.Value.ToString();
textstudentid.Text = string.Empty;
txttamil.Text = string.Empty;
txtenglish.Text = string.Empty;
txtmaths.Text = string.Empty;
txtscience.Text = string.Empty;
txtsocialscience.Text = string.Empty;
SqlDataAdapter adp = new SqlDataAdapter(com);
DataSet ds = new DataSet();
adp.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
tblid.Visible = true;
txtid.Text = ds.Tables[0].Rows[0]["id"].ToString();
txttamil.Text = ds.Tables[0].Rows[0]["Tamil"].ToString();
txtenglish.Text = ds.Tables[0].Rows[0]["English"].ToString();
txtmaths.Text = ds.Tables[0].Rows[0]["Maths"].ToString();
txtscience.Text = ds.Tables[0].Rows[0]["Science"].ToString();
txtsocialscience.Text = ds.Tables[0].Rows[0]["SocialScience"].ToString();
}
else
{
tblid.Visible = false;
output.Text = Output;
}
}
What I have done:
Step 1
When I enter invalid id (which means id doesnot contain in student table) and search, it shows "doesn't exist".
Step 2
When I enter valid id (which means id contains in student and also contain in studentresult table) and search, it shows student marks, if I want to edit the marks and update, so it shows "marks updated".
Step 3
But when I enter id (which means id contains in student but doesn't contain in studentresult table) and search, it works updated function again with all the textboxes contains 0, instead it works insertion.
May I know, what my mistake in the above code?
Can anyone guide me?
I'm struggling for an hour, I'm beginner in .net.
Thanks,
sp_studentresult is broken: it should not insert into studentresult if there already is a row for the given id. Just add
AND NOT EXISTS (SELECT * FROM studentresult WHERE id_student=#id_student)
to
ELSE IF EXISTS (SELECT * FROM student WHERE id=#id_student)
Resulting to:
ALTER PROCEDURE sp_studentresult
(
#id int,
#output varchar(50) output,
#id_student varchar(50),
#Tamil Varchar (100),
#English varchar (50),
#Maths Varchar (50),
#Science Varchar (50),
#SocialScience Varchar (50)
)
AS
IF NOT EXISTS (SELECT * FROM student WHERE id=#id_student)
BEGIN
SET #output='Doesn not EXIST'
END
ELSE IF EXISTS (SELECT * FROM student WHERE id=#id_student)
AND NOT EXISTS (SELECT * FROM studentresult WHERE id_student=#id_student)
BEGIN
INSERT into studentresult (id_student,Tamil,English,Maths,Science,SocialScience) values (#id_student,#Tamil,#English,#Maths,#Science,#SocialScience)
SET #output='Inserted'
END
SELECT * from studentresult where id_student=#id

New Row into SQL Server with Data Set [asp.net, c#]

I have this code:
SqlConnection cnn = new SqlConnection();
cnn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
cnn.Open();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "select * from Szkoda";
cmd.Connection = cnn;
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
DataSet ds = new DataSet();
da.Fill(ds, "Szkoda");
SqlCommandBuilder cb = new SqlCommandBuilder(da);
DataRow drow = ds.Tables["Szkoda"].NewRow();
drow["Likwidator"] = tbLikwidator.Text;
drow["FirmaObslugujaca"] = DdFirma.Text;
drow["StanSzkody"] = DdStan.Text;
drow["CzyRegres"] = DdRegres.Text;
drow["KrajZdarzenia"] = DdKraj.Text;
ds.Tables["Szkoda"].Rows.Add(drow);
da.Update(ds, "Szkoda");
The question is how to get the inserted record ID? I read about scope but I don't know how I can use this in above code.
I want to get last ID to redirect to view form after save new record.
I'm looking for simplest solution:)
You can't do that directly from the Update command of the DataAdapter. You need to prepare a custom insert command that contains two commands. The first insert your record, the second one returns the last inserted id from your connection
string insertText = #"INSERT INTO Szkoda (Likwidator,FirmaObslugujaca,
StanSzkody, CzyRegres, KrajZdarzenia)
values (#lik, #fir, #sta, #czy, #kra);
SELECT SCOPE_IDENTITY()";
SqlCommand cmd = new SqlCommand(insertText, connection);
cmd.Parameters.AddWithValue("#lik", tbLikwidator.Text);
cmd.Parameters.AddWithValue("#fir", DdFirma.Text);
cmd.Parameters.AddWithValue("#sta", DdStan.Text);
cmd.Parameters.AddWithValue("#cay", DdRegres.Text);
cmd.Parameters.AddWithValue("#kra", DdKraj.Text);
object result = cmd.ExecuteScalar();
if(result != null)
{
int lastInsertedID = Convert.ToInt32(result);
// now insert the row in your dataset table but instead of
// da.Update(ds, "Szkoda"); call
ds.Tables["Szkoda"].AcceptChanges();
}
Of course this should go alongside with your existing code, but instead of calling Update just call AcceptChanges to your datatable to confirm the new record in your table
Aftre insert the record into table(using sql query, not stored procedure) from c# code, you can use Get Records function to Select last record id(not recommended, because in muliuser case, this will be wrong) using max() fucntion.
select * from Szkoda where ID IN (select max(id) from Szkoda)
If you are using Stored Procedure to insert data, then Use SCOPE_Identity() in stored procedure, and use Output parameter to get value in c# code.
CREATE PROCEDURE dbo.testSP
#Col1 VARCHAR(50),
#Col2 VARCHAR(20),
#new_identity INT = NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.TestTable(Col1, Col2) SELECT #Col1, #Col2;
SET #new_identity = SCOPE_IDENTITY();
END
GO
Refer this Return identity of last inserted row from stored procedure

MaxLength of column seems to be always -1 for the string fields in the datatable C#

All my data table column fields from the stored procedure is string fields as like given below
[Account Code] varchar(10),
Filler1 varchar(5),
[Accounting Period] varchar(7),
[Transaction Date] varchar(8),
Filler2 varchar(2),
[Record Type] varchar(1),
[Source] varchar(2),
[Journal No] varchar(5),
[Journal Line] varchar(7)
Using the below code only I am picking the value from the SP to the dataset as given below
public DataSet InvoicesToSageExtractGoodsIn(string invoiceDateFrom)
{
SqlConnection conn = null;
DALFactory dalFactory = null;
SqlDataAdapter da = null;
try
{
DataSet dsInvoiceCustomer = new DataSet();
dalFactory = new DALFactory();
conn = new SqlConnection(dalFactory.ConnectionStringVI);
conn.Open();
SqlCommand sqlCommand = new SqlCommand("prc_ReturnSageExtractGoodsIn", conn);
sqlCommand.CommandType = CommandType.StoredProcedure;
DALSystemTable dst = new DALSystemTable(this.dao);
sqlCommand.CommandTimeout = Convert.ToInt32(dst.GetSystemConstant("CommandTimeOut"));
SqlParameter param1 = sqlCommand.Parameters.Add("#InvoiceDateFrom", SqlDbType.DateTime);//VI-165
param1.Direction = ParameterDirection.Input;
param1.Value = invoiceDateFrom;
DataSet dsInvoice = new DataSet("VisionInvoicing");
DataTable dtInvoiceNos = new DataTable("tblSageExtractGoodsIn");
da = new SqlDataAdapter(sqlCommand);
da.Fill(dsInvoice);
dsInvoice.Tables[0].TableName = "tblGenerateInvoice";
return dsInvoice;
}
catch (Exception ex)
{
throw new DatabaseException(ex.Message, ex);
}
}
When I try to pick the MaxLength of the column (dtSAGEExtract.Columns[i].MaxLength) from that dataset table it always shows -1 value.
foreach (DataRow drExtract in dtSAGEExtract.Rows)
{
int fieldCount = (dtSAGEExtract.Columns.Count);
for (int i = 0; i < fieldCount; i++)
{
int length = dtSAGEExtract.Columns[i].MaxLength;
writer.Write(drExtract[i].ToString().PadRight(length));
}
writer.WriteLine();
}
writer.Close();
Does anyone have any idea why it is always showing -1 for all the fields?
First you need to add your DataTable to the DataSet to make it work after you created the DataTable because they are not connected in your example and filling the DataSource has no impact on the DataTable created in the next line so that you can use the additional schema information:
dsInvoice.Tables.Add(dtInvoiceNos);
then you need to call the SqlDataAdapter.FillSchema Method on your SqlDataAdapter to get more information from your database then just the data when using only the Fill method
da.FillSchema(dtInvoiceNos, SchemaType.Source);
da.Fill(dsInvoice);
The fill operations must be called after you added the table to the dataset.
It does not represent the MaxLength of DataTable column. It is not depend on database schema either.
It return -1 because it is default value when you do not set anything.
http://msdn.microsoft.com/en-us/library/system.data.datacolumn.maxlength(v=vs.110).aspx
Because you not fill schema to dataset.
Normaly -1 is default length of column.
You should use:
da.FillSchema(dsInvoice, SchemaType.Mapped)
UPDATE:
DataTable dtInvoiceNos = dsInvoice.Tables[0];
Please check: http://msdn.microsoft.com/en-us/library/229sz0y5(v=vs.110).aspx

asp.net C# sql query dependant on session data

I have a Session, which is list int, and I need to make a query that will take from a database only those rows that have the PK value that exists in Session.
I was thinking of doing it with the IN function, or making a new datatable with 1 collumn and values from the Session and doing a double join, probably left...
I just dont know how to make a table from a list.
What I have so far:
String ConnString = "Data Source=BRACO-PC\SQL1;Initial Catalog=DiplomskiSQL1SQL;Integrated Security=True";
SqlConnection Conn = new SqlConnection(ConnString);
Conn.Open();
DataTable ukosarici = new DataTable();
SqlDataAdapter da = new SqlDataAdapter("Select Proizvodi.ime, TipProizvoda.tip, Proizvodi.dimenzije, Proizvodi.cijena from Proizvod LEFT JOIN TipProizvoda On Proizvod.tip=TipProizvoda.id_t WHERE Proizvod.id_p IN ", Conn);
SqlCommandBuilder cmd = new SqlCommandBuilder(da);
da.Fill(ukosarici);
GridView1.DataSource = ukosarici;
GridView1.DataBind();
Conn.Close();
Create a temporary table or table variable, insert the ints into it using INSERT or BULK INSERT, do a join in the SQL query then drop the temp table or table variable.
There are many ways you could do this, but one of my preferred methods is to serialize the list to a CSV, e.g. '1,3,5,33'. I then use a custom SQL Table function to de-serialize the list and filter in the database:
SELECT * FROM mytable t
JOIN dbo.ufn_CSVtoTextList('1,3,5,33' , ',') csv
ON csv.[Entry] = t.Id
The ufn_CSVtoTextList function CREATE script is below:
CREATE FUNCTION [dbo].[ufn_CSVToTextlist] ( #StringInput nVARCHAR(max) ,#SepChar nchar(1) = ',')
RETURNS #OutputTable TABLE ( [Entry] nVarchar(255), [index] int identity (0,1) )
AS
BEGIN
DECLARE #Entry nVarChar(255)
WHILE LEN(#StringInput) > 0
BEGIN
SET #Entry = LEFT(#StringInput,
ISNULL(NULLIF(CHARINDEX(#SepChar, #StringInput) - 1, -1),
LEN(#StringInput)))
SET #StringInput = SUBSTRING(#StringInput,
ISNULL(NULLIF(CHARINDEX(#SepChar, #StringInput), 0),
LEN(#StringInput)) + 1, LEN(#StringInput))
INSERT INTO #OutputTable ( [Entry] )
VALUES ( #Entry )
END
RETURN
END
Try by changing your SqlDataAdapter Call as follows
List<int> list ; // Assign with your session int list values
List<string> l2 = list.ConvertAll<string>(delegate(int i) { return i.ToString(); });
string query = "Select Proizvodi.ime, TipProizvoda.tip, Proizvodi.dimenzije, Proizvodi.cijena from Proizvod LEFT JOIN TipProizvoda On Proizvod.tip=TipProizvoda.id_t WHERE Proizvod.id_p IN (";
query = query + string.Join(",", l2.ToArray()) + ")";
SqlDataAdapter da = new SqlDataAdapter(query, Conn);

Categories