How to get MySQL time fraction with Devart dotConnect Express MySQL? - c#

Assume that I have a table like this:
CREATE TABLE `table1` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`date` date,
`timestamp2` timestamp(2),
`datetime3` datetime(3),
`time6` time(6),
PRIMARY KEY (`id`)
);
Here's the sample inserts:
insert into table1(`date`,`timestamp2`,datetime3,time6)
values('2000-01-01','2001-01-01 01:01:01.23',
'2002-01-01 01:01:01.243','01:01.234893');
insert into table1(`date`,`timestamp2`,datetime3,time6)
values(null,null,null,null);
and I get the data in C# like this:
using Devart.Data.MySql;
DataTable dt = new DataTable();
StringBuilder sb = new StringBuilder();
using (MySqlConnection conn = new MySqlConnection(ConnString))
{
using (MySqlCommand cmd = new MySqlCommand())
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "select * from table1;";
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(dt);
conn.Close();
}
}
int row = 0;
foreach (DataRow dr in dt.Rows)
{
row++;
sb.AppendLine();
sb.AppendLine("Row " + row);
foreach (DataColumn dc in dt.Columns)
{
object ob = dr[dc.ColumnName];
string typeName = ob.GetType().ToString();
sb.AppendLine($"{dc.ColumnName} = {typeName} | value = " + ob + "");
}
}
richTextBox1.Text = sb.ToString();
and here's the output:
Row 1
id = System.Int64 | value = 1
date = System.DateTime | value = 01/01/2000 12:00:00 AM
timestamp2 = System.DateTime | value = 01/01/2001 1:01:01 AM
datetime3 = System.DateTime | value = 01/01/2002 1:01:01 AM
time6 = System.TimeSpan | value = 01:01:00.2348930
Row 2
id = System.Int64 | value = 2
date = System.DBNull | value =
timestamp2 = System.DBNull | value =
datetime3 = System.DBNull | value =
time6 = System.DBNull | value =
As you can see that the Devart Express dotConnect MySQL returns time fraction in DateTime in C#. The time fraction is lost.
How to get the time fraction?
*Note: For some reason I must use Devart Express dotConnect.

Fractional second values are stored in DataTime structure.
Kindly note, that the default ToString method of DateTime doesn't show the fraction of a second.
To extract the string representation of a time's millisecond component, call the date and time value's DateTime.ToString(String) or ToString method, and pass the fff or FFF custom format pattern alone or with other custom format specifiers as the format parameter: https://learn.microsoft.com/en-us/dotnet/standard/base-types/how-to-display-milliseconds-in-date-and-time-values.
To see the time fraction in your test application:
foreach (DataColumn dc in dt.Columns)
{
var ob = dr[dc.ColumnName];
string typeName = ob.GetType().ToString();
string val;
if (typeName == "System.DateTime") val = ((DateTime)ob).ToString("yyyy.MM.dd hh: mm:ss.fff");
else val = ob.ToString();
Console.WriteLine($"{dc.ColumnName} = {typeName} | value = " + val + "");
}
The result:
Row 1
id = System.Int64 | value = 1
date = System.DateTime | value = 2000.01.01 12: 00:00.000
timestamp2 = System.DateTime | value = 2001.01.01 01: 01:01.230
datetime3 = System.DateTime | value = 2002.01.01 01: 01:01.243
time6 = System.TimeSpan | value = 01:01:00.2348930
Row 2
id = System.Int64 | value = 2
date = System.DBNull | value =
timestamp2 = System.DBNull | value =
datetime3 = System.DBNull | value =
time6 = System.DBNull | value =
Press any key to continue . . .

Related

some selected fields as Pivote column ASP.NET

I want to show some selected columns as my SQL column and the rest of the column should be pivot. My output should be: Please help me any idea ?
Pivot table
ID | Employee_ID | 01-sep-2019 | 02-sep-2019 | 03-sep-2019
───┼─────────────┼─────────────┼─────────────┼────────────
1 | 1001 | P | A | P
2 | 1002 | A | P | A
3 | 1003 | A | P | P
Original table
ID | Employee_ID |STATUS | Created_Date
───┼─────────────┼───────┼─────────────
1 | 1001 | P | 01-sep-2019
2 | 1002 | A | 02-sep-2019
3 | 1003 | P | 03-sep-2019
I use 2 `GridView to show data but it's applicable for all column that I don't need. Could you please help me?
private DataTable PivotTable(DataTable origTable) {
DataTable newTable = new DataTable();
DataRow dr = null;
//Add Columns to new Table
for (int i = 0; i <= origTable.Rows.Count; i++) {
newTable.Columns.Add(new DataColumn(origTable.Columns[i].ColumnName, typeof(String)));
}
//Execute the Pivot Method
for (int cols = 0; cols < origTable.Columns.Count; cols++) {
dr = newTable.NewRow();
for (int rows = 0; rows < origTable.Rows.Count; rows++) {
if (rows < origTable.Columns.Count) {
dr[0] = origTable.Columns[cols].ColumnName; // Add the Column Name in the first Column
dr[rows + 1] = origTable.Rows[rows][cols];
}
}
newTable.Rows.Add(dr); //add the DataRow to the new Table rows collection
}
return newTable;
}
private void BindGridView() {
string strConnString = ConfigurationManager.ConnectionStrings["SQLDBConnection"].ConnectionString;
SqlConnection con = new SqlConnection(strConnString);
try {
con.Open();
string sqlStatement = "SELECT Top(5)* FROM tbl_QC_Attandence";
SqlCommand sqlCmd = new SqlCommand(sqlStatement, con);
SqlDataAdapter sqlDa = new SqlDataAdapter(sqlCmd);
DataTable dt = new DataTable();
sqlDa.Fill(dt);
if (dt.Rows.Count > 0) {
//Bind the First GridView with the original data from the DataTable
grdorignal.DataSource = dt;
grdorignal.DataBind();
//Pivot the Original data from the DataTable by calling the
//method PivotTable and pass the dt as the parameter
DataTable pivotedTable = PivotTable(dt);
grdpivote.DataSource = pivotedTable;
grdpivote.DataBind();
}
} catch (System.Data.SqlClient.SqlException ex) {
string msg = "Fetch Error:";
msg += ex.Message;
throw new Exception(msg);
} finally {
con.Close();
}
}
ORIGINAL TABLE
ID Employee_ID STATUS Created_Date
1 1001 P 01-sep-2019
2 1002 A 02-sep-2019
3 1003 P 03-sep-2019
PIVOT TABLE
ID Employee_ID 01-sep-2019 02-sep-2019 03-sep-2019
1 1001 P A P
2 1002 A P A
3 1003 A P P
I have create a dynamic query which can help you, but null can be replaced with 'A' in code side, try below one
DECLARE
#columns NVARCHAR(MAX) = '',
#sql NVARCHAR(MAX) = '',
#SelectColumnNames AS NVARCHAR(MAX);
SELECT
#columns += QUOTENAME([Created_Date]) + ','
FROM
Employee
ORDER BY
[Created_Date];
SET #columns = LEFT(#columns, LEN(#columns) - 1);
Select #SelectColumnNames = ISNULL(#SelectColumnNames + ',','')
+ 'ISNULL(' + QUOTENAME([STATUS]) + ', 0) AS '
+ QUOTENAME([STATUS])
from (SELECT distinct [STATUS] from Employee) as Employees
print #SelectColumnNames
SET #sql =
N'Select * from(
select Created_Date,[STATUS],ID,Employee_ID
from Employee
)t
PIVOT(
MAX([STATUS])
FOR [Created_Date] IN ('+ #columns +')
) AS pivot_table
';
EXECUTE sp_executesql #sql;

Is possible to combine SIMPLE values and MULTIVALUEs in conditions when you are doing a SELECT on UniVerse Database with UNNEST

From Universe prompt I run my command
> SELECT SUM(MONTREMB),SUM(MONTCAP),SUM(MONTINT) FROM UNNEST TAVANCE.001 ON AVA_ASS WHERE ETAT =1 AND MAXDTEREMB >= '2019-01-01' AND MAXDTEREMB <= '2019-02-15' AND MONTREMB = 0;
And I get totals
SUM ( MONTREMB ) SUM ( MONTCAP ) SUM ( MONTINT )
0 -599300 2144637
This is my table DICT TAVANCE.001
Field......... Field. Field........ Conversion.. Column......... Output Depth &
Name.......... Number Definition... Code........ Heading........ Format Assoc..
#ID D 0 TAVANCE.001 10L S
KEYCREDIT D 0 KEYCREDIT 15L S
ETAT D 1 ETAT 1R S
MATRICULE D 2 MATRICULE 12L S
MONTANT D 3 MONTANT 12R S
INTERET D 4 INTERET 2R S
DUREE D 6 DUREE 2R S
DTEAVANCE D 7 D/E DTEAVANCE 10L S
MENSUALITE D 9 MENSUALITE 12R S
DTEREMB D 10 D/E DTEREMB 10L M AVA_A
SS
PERIORMBT D 10 PERIORMBT 20R S
MONTREMB D 11 MONTREMB 12R M AVA_A
SS
MONTINT D 12 MONTINT 12R M AVA_A
SS
MONTCAP D 14 MONTCAP 12R M AVA_A
I.NOM I TRANS(TSIGNAG I.NOM 40L S
PE.031,MATRIC
ULE,NOM,'X')
AVA_ASS PH DTEREMB
MONTREMB
#SELECT PH MATRICULE
I.NOM MONTANT
RBTCAP
DTEAVANCE
ETAT PMT
#EMPTY.NULL X
25 records listed.
In the condition of my select command, ETAT and MAXDTEREMB are simple value but MONTREMB is multivalue
The problem is that in my c# problem with the same SELECT command
if (checkInteret.Checked == true)
sRequete = "SELECT SUM(MONTREMB),SUM(MONTCAP),SUM(MONTINT) FROM UNNEST " + tableGroupe + " ON AVA_ASS WHERE (ETAT <> 1 AND ETAT <> 2) AND DTEREMB <= '" + sDateFin + "' AND MONTREMB = 0 ";
U2DataAdapter da = new U2DataAdapter(sRequete, con);
DataSet ds = new DataSet();
da.Fill(ds, "TAVANCE");
con.Close();
con.Open();
tAvance = null;
tAvance = ds.Tables["TAVANCE"];
With tavance.rows.count, not result is displayed. Is there an error in my SELECT command.
For more details, I'm using U2toolkit for .Net to connect to Universe database
using U2.Data.Client;
U2Connection con = new U2Connection();
UniSession session = null;
U2ConnectionStringBuilder conn_str = new U2ConnectionStringBuilder();
string UserId = "root";
string PassWord = "xxxxxx";
string server = "192.xxxxx";
string Database = "LACCOUNT";
string ServerType = "UNIVERSE";
conn_str.UserID = UserId;
conn_str.Password = PassWord;
conn_str.Server = server;
conn_str.Database = Database;
conn_str.FirstNormalForm = false;
conn_str.ExpandMultiValueRows = true;
conn_str.ServerType = ServerType;
conn_str.Connect_Timeout = 1200;
con.ConnectionString = conn_str.ToString();
con.Open();

How to get each data in each row C# & SQL

Let's say I have a table with 3 columns like this:
ID | NAME | Subject
---+------+----------
1 | Mark | English
1 | Mark | Math
2 | Matt | Math
2 | Matt | English
1 | Mark | History
How to get each subject of "Mark" like English, Math, History (order by) that will match to their id in every row in column subject? Because I only get the first subject which is "English" or the first row.
string sql = "select * from tbl_Student where ID like '"+ID.Text+"'";
cm = new SqlCommand(sql, cn);
dr = cm.ExecuteReader();
while (dr.Read())
{
Subject1.Text = dr["Subject"].ToString();
Subject2.Text = dr["Subject"].ToString();
Subject3.Text = dr["Subject"].ToString();
}
dr.Close();
You replace the value of Subject.Text in each loop. That means it contains only the last value.
You should concatenate the string
Subject.Text += dr["Subject"].ToString();
I would definitely change the like operator to an equal(=) operator.
And you are having always one value in the loop, concatenate the strings.
Use StringBuilder:
StringBuilder sb = new StringBuilder();
while (dr.Read())
{
sb.Append(dr["Subject"].ToString());
sb.Append(",");
}
result = sb.ToString().TrimEnd(',');
UPDATE
use switch/case then, to determine your id and assign its value to proper TextBox:
while (dr.Read())
{
string subject = dr["Subject"].ToString();
switch (dr["ID"].ToString())
{
case "1":
Subject1.Text += subject + " ";//$"{subject} "; //or use string builder as I've showed above
break;
case "2":
Subject2.Text += subject + " ";//$"{subject} ";
break;
case "3":
Subject3.Text += subject + " ";//$"{subject} ";
break;
default:
break;
}
}
Also, please use Parameterized Queries.

c# - How to get specific values out of a DataTable using LINQ

I have an Access table which looks like this:
ID | col_1 | col_2 | col_n
1 | 12345 | ... | ...
1 | null | ... | ...
1 | null | ... | ...
2 | 67891 | ... | ...
What I want to accomplish is to get all col_1 with the ID 1 if there is at least one value in col_1 with that ID. So my result would be:
ID | col_1
1 | 12345
1 | null
1 | null
The following code gets me the all the values of ID and col_1 and stores them in a DataTable results0.
public void ConnectDB(string path, string query0, string query1)
{
string connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Persist Security Info=False";
try
{
using (OleDbConnection conn = new OleDbConnection(connString))
{
DataTable results0 = new DataTable();
OleDbCommand cmd = new OleDbCommand(query0, conn);
conn.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
adapter.Fill(results0);
}
}
catch (System.InvalidOperationException inv)
{
MessageBox.Show(inv.Message);
throw;
}
}
I wanted to use LINQ for this issue, since I don't want to loop through the rows and tried a few things without success. At first I thought something like this would give me the relevant values (which it does)
int id = 1;
for (int i = 0; i < 9; i++) // iterate through IDs and increment
{
IEnumerable<String> Ids =
results0
.AsEnumerable()
.Where(row => row.Field<Int32>("ID") == id)
.Select(row => row.Field<String>("FERI"));
id+=1;
}
but I'm not sure how to rephrase it in an if-statement. Something like "If ID = 1 and at least one value in col_1 get range of rows with ID = 1"
I hope this isn't too confusing.
Any help and suggestions are appreciated!
Update: I'm still having trouble getting the relevant rows. I tried using DataRow[], selecting all the rows with ID = 1 and iterating with foreach-loops but this doesn't seem really efficient. Can anyone help?
To get the list of records with ID==1 from the Database assuming database with name "DBName", we will have:
public DBName _dbContext = new DBName ();
and then using following LINQ query we will get result:
_dbContext.TableName.Where(u => u.ID == 1).Select(u => u.col_1 ).ToList();
Real easy.
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("col_1", typeof(int));
dt.Columns["col_1"].AllowDBNull = true;
dt.Rows.Add(new object[] { 1, 12345});
dt.Rows.Add(new object[] { 1, null});
dt.Rows.Add(new object[] { 1, null});
dt.Rows.Add(new object[] { 2, 67891});
int id = 1;
DataTable dt2 = dt.AsEnumerable().Where(x => x.Field<int>("ID") == id).CopyToDataTable();

DateTime Conversion error when executing SqlDataReader

I'm getting an issue when executing a reader to retrieve some DateTimes from a table.
First, I have one page transferring over some variables to another page:
//calStart.SelectedDate is a DateTime value
Response.Redirect("SpecialReports_Results.aspx?userListValues=" + userListValues + "&groupListValues=" + groupListValues + "&calSelected=" + calStart.SelectedDate);
Then, on the new page:
//To retrieve the values that were sent over
string userListValues = Request.QueryString["userListValues"];
string groupListValues = Request.QueryString["groupListValues"];
string dateSelected = Request.QueryString["calSelected"];
// SQL Server connection stuff + string argument
SqlCommand command2 = new SqlCommand();
command2.Connection = gconn;
String sql2 = "SELECT MAX([Day]) as TheDay FROM Days WHERE User_ID = #User_ID AND [Day] < '#dateSelected' AND NOT EXISTS (SELECT 1 FROM Days WHERE User_ID = #User_ID AND [DAY] >= '#dateSelected')";
command2.CommandText = sql2;
command2.Parameters.Add(new SqlParameter("#User_ID", ""));
command2.Parameters.Add(new SqlParameter("#dateSelected", dateSelected));
List<string> dates = new List<string>();
//userID is a List<string>
foreach (string str in userID)
{
command2.Parameters["#User_ID"].Value = str;
using (SqlDataReader reader = command2.ExecuteReader())
{
while (reader.Read()) //Getting error here: Conversion failed when converting datetime from character string.
{
if (reader.HasRows)
{
dates.Add(reader["Day"].ToString());
}
}
}
}
The table Days is set up like so:
User_ID | Day
----------------------------------
10 | 2010-11-09 00:00:00.000
20 | 2015-12-06 00:00:00.000
30 | 2012-01-12 00:00:00.000
40 | 2013-07-23 00:00:00.000
The Day column is of type DateTime.
I have tried converting the string dateSelected and the List<string> dates to DateTime by doing:
DateTime confirmedDate = DateTime.Parse(dateSelected);
List<DateTime> dates = new List<DateTime>()
But I get the same error.
Note: The SQL statement does work when executed in Microsoft's SQL Server Management Studio.
I think you need to delete single quotes on your '#dateSelected'.
With that, your code see it as a string literal, not a parameter.
String sql2 = "SELECT MAX([Day]) as TheDay FROM Days WHERE User_ID = #User_ID AND [Day] < #dateSelected AND NOT EXISTS (SELECT 1 FROM Days WHERE User_ID = #User_ID AND [DAY] >= #dateSelected)";
Since there is no implicit conversation from string to datetime, your reader try to convert this #dateSelected string literal to datetime and it fails.

Categories