Insert into 120 columns from 120-indexed array - c#

I have column names like this
Id
,Test
,[H01_1]
,[H01_2]
,[H01_3]
,[H01_4]
,[H01]
,[H02_1]
,[H02_2]
,[H02_3]
,[H02_4]
,[H02]
,[H03_1]
,[H03_2]
,[H03_3]
,[H03_4]
,[H03]
,[H04_1]
,[H04_2]
,[H04_3]
,[H04_4]
,[H04]
,[H05_1]
,[H05_2]
,[H05_3]
,[H05_4]
,[H05]
,[H06_1]
,[H06_2]
,[H06_3]
,[H06_4]
,[H06]
,[H07_1]
,[H07_2]
,[H07_3]
,[H07_4]
,[H07]
,[H08_1]
,[H08_2]
,[H08_3]
,[H08_4]
,[H08]
,[H09_1]
,[H09_2]
,[H09_3]
,[H09_4]
,[H09]
,[H10_1]
,[H10_2]
,[H10_3]
,[H10_4]
,[H10]
,[H11_1]
,[H11_2]
,[H11_3]
,[H11_4]
,[H11]
,[H12_1]
,[H12_2]
,[H12_3]
,[H12_4]
,[H12]
,[H13_1]
,[H13_2]
,[H13_3]
,[H13_4]
,[H13]
,[H14_1]
,[H14_2]
,[H14_3]
,[H14_4]
,[H14]
,[H15_1]
,[H15_2]
,[H15_3]
,[H15_4]
,[H15]
,[H16_1]
,[H16_2]
,[H16_3]
,[H16_4]
,[H16]
,[H17_1]
,[H17_2]
,[H17_3]
,[H17_4]
,[H17]
,[H18_1]
,[H18_2]
,[H18_3]
,[H18_4]
,[H18]
,[H19_1]
,[H19_2]
,[H19_3]
,[H19_4]
,[H19]
,[H20_1]
,[H20_2]
,[H20_3]
,[H20_4]
,[H20]
,[H21_1]
,[H21_2]
,[H21_3]
,[H21_4]
,[H21]
,[H22_1]
,[H22_2]
,[H22_3]
,[H22_4]
,[H22]
,[H23_1]
,[H23_2]
,[H23_3]
,[H23_4]
,[H23]
,[H24_1]
,[H24_2]
,[H24_3]
,[H24_4]
,[H24]
And I am trying to write a simple INSERT with dapper (SQL Server 2014).
For the Id and Test I am writing an anonymous object to put into the param but I wasn't sure whats the best way to take a 120 length int? array and insert it into the columns beginning with H
Where index 0 goes to H01_1 and index 1 goes to H01_2 ... etc
I don't want to have to write SQL that says
H01_1 = #H01_1,
H01_2 = #H01_2,
...
And then also have to make an anonymous object that does
H01_1 = array[0],
H01_2 = array[1],
...
One thing I can do is insert just Id and Test and then go back and do an UPDATE on that record. But I am still in the same scenario I was before where I don't know the best way to write an UPDATE in dapper without writing things out 120 times.

If it is possible to change your datatable structure then only follow below design
In your table you have more number of column and find out that your assigned ID as primary . So instead of using above data structure use below ..
ID test column value
01 xyz H01_1 val_H01_1
01 xyz H01_2 val_H01_2
Assign group primary key for ID,test and column..
If it is not possible for changing structure . Then create a XML from your front end data and create Stored procedure like below to excute it . If you go through with http://www.itworld.com/article/2960645/development/tsql-how-to-use-xml-parameters-in-stored-procedures.html then you will get idea.

Related

how to get max id from a table using linq

I have a table Estimation which has an column EstimationNo,i am trying to get the max EstimationNo like this-
var result = cont.SalesEstimateCont.Where(x => x.Org_ID == CurrentOrgId);
var estimationMaxNo = result.Any() ? result.Max(x => x.EstimateNo) + 1 : 1;
var DigitalEstimate = new SalesEstimate()
{
EstimateNo=estimationMaxNo;
};
cont.Estimate.Add(DigitalEstimate );
cont.Savechanges();
but the problem is, if same table is saving by different users at same time its saving the same EstimationNo for both users. like- 10,10
Now, how to handle this issue..please give some solution.
Best strategy is to let db engine (I assume that it is SQL Server) handle incrementing of EstimateNo field. This can be done with identity specification which can be added to normal not primary key field also.
ALTER TABLE SalesEstimateCont drop column EstimateNo
go
ALTER TABLE SalesEstimateContadd Add EstimateNo int NOT NULL IDENTITY (1,1)
Please note: if you have existing data or some data should be modified, you may need some extra effort to achieve this (i.e with temp tables and by setting IDENTITY INSERT ON)
I got a simple answer.I just had to use transacationScope class.
and lock the resource table. like this-
using (TransactionScope scope = new TransactionScope())
{
cont.Database.ExecuteSqlCommand("SELECT TOP 1 * FROM Sales__Estimate WITH (TABLOCKX, HOLDLOCK)");
var result = cont.SalesEstimateCont.Where(x => x.Org_ID == CurrentOrgId);
var estimationMaxNo = result.Any() ? result.Max(x => x.EstimateNo) + 1 : 1;
var DigitalEstimate = new SalesEstimate()
{
EstimateNo=estimationMaxNo;
};
cont.Estimate.Add(DigitalEstimate );
cont.Savechanges();
}
If you can make EstimateNo an Identity column, that is the easiest/best way to fix this. If you can change this to a Guid, that would be another easy way to fix this as PK would be unique regardless of the user.
If you can't do either of these and you must take Max() manually, you might want to consider creating another table that stores the next available number there. Then you can create a new SqlCommnand with a Serializable transaction to lock the table, update the # by 1 and select it back. If two update commands hit at the same time, only one update will run and won't let go until that connection with Serializable transaction gets closed. This allows you to select the newly updated number before the other update runs and get the now "unique" next number.
You can OrderByDescending and then Take the the first record
var estimationMaxNo = result.OrderByDescending(x => x.EstimateNo).Take(1);
It can be done in a single command. You need to set the IDENTITY property for primary id
ALTER TABLE SalesEstimateCont ADD Org_ID int NOT NULL IDENTITY (1,1) PRIMARY KEY

get and post table type using pqxx

Good day, friends. I'm using pqxx and I have some questions.
1. I have two tables:
table1 (table1_id integer) and table2 (table1_id integer, another_id integer) with relation one-to-many.
How I can easy get information in view like: table1_id, vector another_ids?
Now I use serializtion in script (string concat into "%d %d %d...") and deserialization in my c++ code.
Also I need insert value into table1. And how I can do this in one transaction?
2. I call stored procedure like
t.exec("SELECT * FROM my_proc(some_argument)");
May be exists any way to do this like in c#?
Thank you very much!
So, may be it can help someone.
In first case I find and use two ways:
1. Group concat in sql function and deserialization in c++. It fast if table2 has only table1_id and another integer.
2. I call two function: get_table1() and get_table2() with order by table1_id. And then with two pointers I create array of table1:
std::vector<Table1> table1Array;
auto ap = wrk.prepared(GetTable1FuncName).exec();
auto aps = wrk.prepared(GetTable2FuncName).exec();
auto pos = aps.begin();
for (auto row = ap.begin(); row != ap.end(); ++row) {
std::vector<Table2> table2Array;
while (pos != aps.end()
&& row["table1_id"].as(int()) == pos["table1_id"].as(int())) {
table2Array.push_back(Table2(pos["first_id"].as(int()),
pos["second_string"].as(std::string())));
++pos;
}
Table1 tb1(row["table1_id"].as(int()), row["column2"].as(int()),
row["column3"].as(int()), row["column4"].as(int()),
table2Array);
table1Array.push_back(tb1);
}
May be it is not pretty, but it's working.
Insert into database I write for one element. Firstly insert into Table1, and after several lines into Table2. After call pqxx::work.commit().
In second case Not, doesn't exists. Also remember, function always return 1 line! Be careful!

how get datagrdiviewComboboxColumn value member?

i have a small project in c#, in one of my forms i have a datagridview with 3 columns one of the columns is comboboxcolumn that bind with a sql server table id and name, i want to insert the datagridview values into another table in the comboboxcolumn i want to insert the id not a name, anyone can tel me how to do that please? this is my insert code
`
for (int i = 0; i < dgv_student.Rows.Count; i++)
{
sc.add_student(dgv_student.Rows[i].Cells[0].Value.ToString(),
Convert.ToInt32(dgv_student.Rows[i].Cells[1].Value),
dgv_student.Rows[i].Cells[2].Value.ToString());
}
`
the cell[1] the the combobox that display a name not the id.
In your example you have :
Name ID
X X
As your database set. When you are getting this from your database you're probably doing :
myDataGridView.DataSource = GetAllFromMyDatabase(); // Select * from stuff
myDataGridView.DataBind();
Giving you all three columns, and the value. Now, if you want to insert only one column, why not just filter the data you're getting from your database/gridview ?
myComboBox.DataSource = GetOnlyIDFromMyDatabaseOrMyDataGrid(); // Select ID from Stuff
myComboBox.DataBind();
If you're binding your asp.net control with only the data you need, rather than getting everything and then filter, you will have less overhead to think about.

How to Update one table by another table datas using storedprocedure?

I have a Table named Dummywith marks and student id (3 mark fields are there). I have another one table Applicantdetails this table also contains mark fields. what I want to do is I want to updates Dummy tables marks to Applicantdetails table's marks as per student id. I want to do this by mssql Storedprocedure. Any way to achieve it. If we write in code wise it should be like this
qry="select Applicantid,mark1,mark2,mark3 from Dummy"
//saved result to Datatable dt
foreaach(DataRow. rows in dt.rows)
{
string id=Convert.ToString(row["ApplicantID"].tostring();
string mark1=Convert.ToString(row["ApplicantID"].tostring();
string mark2=Convert.ToString(row["ApplicantID"].tostring();
string mark3=Convert.ToString(row["ApplicantID"].tostring();
qry="update Applicantdetails set Mark1=mark1,Mark2=Mark2,Mark3=Mark3
where ApplicantID=id";
}
This format I want to bring in storedprocedure..Please help me
Your Stored procedure would receive #applicationid ? Otherwise it would update all, Create a stored procedure with the following SQL
UPDATE A
SET Mark1= d.mark1, Mark2 = d.mark2, Mark3= d.mark3
FROM ApplicationDetail A
JOIN Dummy d on d.Applicationid = A.Applicationid

Is it a standard to add an auto increment column to a User Defined Table type?

i'm have collection in my client C# app which consist of the 5 columns. In the DB I have created a User defined table type (UDTT) of six columns. the first column is an autom increment which I will be using to fetch each row stored in it. table structure is pSelCRSInfo
while(#cntr <= #pProgDuration)
begin
select
#CRSID=CRSID,
#YearNo=YearNo,
#IsCompulsory=IsCompulsory,
#EntDT=EntDT,
#EmpID=EmpID
from #pSelCRSInfo where CntrNo=#cntr
insert into DefaultCourses
(PRGID,CRSID,YearNo,IsCompulsory,EntDT,EmpID)
values (#newPRGID,#CRSID,#YearNo,#IsCompulsory,#EntDT,#EmpID)
set #cntr = #cntr + 1
end
in it's definition I have added
create type dbo.SelectedCourses
as table
(
CntrNo int not null IDENTITY(1, 1),
CRSID int,
YearNo int,
IsCompulsory varchar(20),
EntDT datetime,
EmpID int
);
go
At the moment i'm struggling with how to pass 5 column collection to a collection that requires 6 column?
Typically do people create UDTT structures with auto increment columns to accept collections? because I could generate the numbers generated by the auto increment column from the client then send that with the collection
thanks
I would say it depends entirely on you. If auto-incremented values suit your purpose then definitely use them. I'd do it.
so assume I have created a UDTT with a auto increment column, then still I should pass 6 column collection like the one below and leave the first column empty
//leave the first column empty
acd.dtCourses.Rows[CollCounter][0] = string.Empty
acd.dtCourses.Rows[CollCounter][1] = dt.Rows[i][2];
acd.dtCourses.Rows[CollCounter][2] = dt.Rows[i][3];
acd.dtCourses.Rows[CollCounter][3] = dt.Rows[i][4];
acd.dtCourses.Rows[CollCounter][4] = DateTime.Today;
acd.dtCourses.Rows[CollCounter][5] = myAcedemics.EmpID;
dtCourses is a datatable to accept the collection and my acd is an object of the business class Academics

Categories