How can I split a string value and insert it in a different column in the same row? - sql

i have column like this (all in varchar)
SIGN ON SIGN OFF SIGN IN SIGN OFF
----------------------- -------- -----------
01-05-2015 / 20-04-2016 NULL NULL
AND i want to do this:
SIGN ON SIGN OFF SIGN IN SIGN OFF
----------------------- -------- -----------
01-05-2015 / 20-04-2016 01-05-2015 20-04-2016
i try with string split from sql 2016 but he had on another line the values not the same.
how can i do it?

You can try below -
DEMO
select
left(colname,charindex('/',colname)-1) as signon,
right(colname,charindex('/',colname)-1) as signoff
from tablename
OUTPUT:
signon signoff
01-05-2015 20-04-2016

You can use string functions:
select col1,
left(col1, charindex('/', col1) - 1),
stuff(col1, 1, charindex('/', col1) + 1, '')
from t;

You can try the following query.
select substring([SIGN ON SIGN OFF],1,charindex('/',[SIGN ON SIGN OFF])-2) as sign_in,
substring([SIGN ON SIGN OFF],charindex('/',[SIGN ON SIGN OFF])+1,len([SIGN ON SIGN OFF])) as sign_off

if i enter manually both answers worked. but for some reason executing was give me an error. so i give up from trying in the Sql code i did in c#.
here my solution that worked fo all cells.
DBHelper.DBHelper da = new DBHelper.DBHelper();
DataTable dt = new DataTable();
dt = da.getAllEmbarques();
foreach (DataRow row in dt.Rows)
{
try
{
List<SqlParameter> p = new List<SqlParameter>();
string nospaces = row[5].ToString().Replace(" ", string.Empty);
string[] newsplit = nospaces.Split('/');
if (newsplit.Count() == 1)
{
string[] newsplit1 = newsplit[0].ToString().Split('-');
DateTime dt1 = new DateTime(Int32.Parse(newsplit1[0]), Int32.Parse(newsplit1[1]), Int32.Parse(newsplit1[2]));
SqlParameter parameter = new SqlParameter("#SIGNIN",SqlDbType.DateTime);
parameter.IsNullable = true;
parameter.Value = dt1;
p.Add(parameter);
parameter = new SqlParameter("#SIGNOFF", SqlDbType.DateTime);
parameter.IsNullable = true;
parameter.Value = DBNull.Value;
p.Add(parameter);
p.Add(new SqlParameter("#id", row[7].ToString()));
da.UpdateStringsplitEmbarques(p.ToArray());
}
else
if (newsplit.Count() == 2)
{
string[] newsplit1 = newsplit[0].ToString().Split('-');
string[] newsplit2 = newsplit[1].ToString().Split('-');
DateTime dt1 = new DateTime(Int32.Parse(newsplit1[0]), Int32.Parse(newsplit1[1]), Int32.Parse(newsplit1[2]));
DateTime dt2 = new DateTime(Int32.Parse(newsplit2[0]), Int32.Parse(newsplit2[1]), Int32.Parse(newsplit2[2]));
SqlParameter parameter = new SqlParameter("#SIGNIN", SqlDbType.DateTime);
parameter.IsNullable = true;
parameter.Value = dt1;
p.Add(parameter);
parameter = new SqlParameter("#SIGNOFF", SqlDbType.DateTime);
parameter.IsNullable = true;
parameter.Value = dt2;
p.Add(parameter);
p.Add(new SqlParameter("#id", row[7].ToString()));
da.UpdateStringsplitEmbarques(p.ToArray());
}
}
catch
{
}
}
thanks you all for the time spending answering my question.
best regards

Related

Getting error: failed to convert parameter value from a String to a DateTime

I get this error:
Failed to convert parameter value from a String to a DateTime.
The error occurs at ExecuteDataset(Connection, cmd, query, parameters);
Code:
int paramCount = 2 + results.Count;
SqlParameter[] sqlParam = new SqlParameter[2];
sqlParam[0] = new SqlParameter("#FROMDATE", SqlDbType.DateTime);
sqlParam[0].Value = Convert.ToDateTime(SearchRequest.FromDate).ToString("yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
results.Add(sqlParam[0]);
sqlParam[1] = new SqlParameter("#TODATE", SqlDbType.DateTime);
sqlParam[1].Value = Convert.ToDateTime(SearchRequest.ToDate).ToString("yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
results.Add(sqlParam[1]);
foreach (var o in strCode)
{
SqlParameter paramRef = new SqlParameter();
paramRef.ParameterName = "#Param" + results.Count;
paramRef.Value = o;
results.Add(paramRef);
lstParam.Add(paramRef.ParameterName);
}
SqlParameter[] sqlParams = new SqlParameter[paramCount];
sqlParams = results.ToArray();
string Query;
Query = "select StudID,StudName from StudentDetails
where CourseCode in ({2}) and Coursedate between #FROMDATE and #TODATE";
var inClause = String.Join(",", lstParam);
Query = Query.Replace("{2}", inClause);
Issue is resolved, I was passing incorrect date format...
During debugging DATE do read it as e.g 20130831 which I changed it to 2013-08-31 format and it worked for me...

SQL Server DataAdapter is not filling datatable

I am running code to fill a dataset from a SQL Server table, but for some reason it is not filling the datatable. I have run the stored procedure with the values when stepping through the code and it returns rows. I have checked via SQL Server Profiler what command runs and then executed the same command through SQL Server Management Studio and it returns rows, but for some reason in Visual Studio it returns no rows, yet it is not returning any exception.
The code is :
try
{
using (SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["Intranet"].ConnectionString))
{
switch (command)
{
case "radiobutton":
string school = ParameterString[0];
using (SqlDataAdapter da = new SqlDataAdapter(GET_TEMPLATE_NAMES, cnn))
{
DataTable dt = new DataTable();
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.Parameters.AddWithValue("#TemplateforSchool", school);
cnn.Open();
da.Fill(dt);
lstTemplates.DataSource = dt;
lstTemplates.DataBind();
}
break;
case "listbox": // If the listbox triggers the callback then update the grid
switch (radSchools.SelectedItem.Text)
{
case "Junior School":
StartYear = 1;
EndYear = 5;
break;
case "Middle School":
StartYear = 6;
EndYear = 8;
break;
case "Senior School":
StartYear = 9;
EndYear = 12;
break;
}
string TemplateName = ParameterString[0];
int DetentionCount = Convert.ToInt16(ParameterString[1]);
string DetentionType = ParameterString[2];
using (SqlDataAdapter da = new SqlDataAdapter(GET_CAREGIVER_EMAIL_LIST, cnn))
{
DataTable dt = new DataTable();
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "#DetentionType",
SqlDbType = SqlDbType.VarChar,
Value= DetentionType
});
da.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName="#DetentionCounter",
SqlDbType=SqlDbType.Int,
Value=DetentionCount
});
da.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "#StartYear",
SqlDbType = SqlDbType.Int,
Value = StartYear
});
da.SelectCommand.Parameters.Add(new SqlParameter
{
ParameterName = "#EndYear",
SqlDbType = SqlDbType.Int,
Value = EndYear
});
cnn.Open();
da.Fill(dt);
gdvCaregiverEmailList.DataSource = dt;
gdvCaregiverEmailList.DataBind();
}
break;
}
}
}
catch(Exception ex)
{
}
The problem is in the listbox: section of the switch statement. The SqlDataAdapter works fine in the radio button section of the switch.
I am not sure what I am missing so any help would be much appreciated.
I have checked SqlDataAdapter does not fill DataSet and also SqlDataAdapter not filling DataTable but the first was not relevant to my situation and the second had no accepted answer that I could find.
The SQL Server stored procedure that I am calling is
ALTER PROCEDURE [dbo].[GetCaregiverEmailList]
#DetentionType CHAR(2),
#DetentionCounter INT,
#StartYear INT,
#EndYear INT
AS
BEGIN
SELECT DISTINCT
sdc.StudentCode, s.Student#, s.GIVEN_NAME, s.SURNAME,
sdc.DetentionCount, sdc.DetentionType,
s.GIVEN_NAME + ' ' + s.SURNAME AS FullName,
LTRIM(s.CURRENT_YEAR) AS CurrentYear,
i.EMAIL_HOME, RTRIM(i.SALUTATION) AS EmailTitle,
ax.CORR_PREFERENCE, ar.CAREGIVER_NO
FROM
StudentDetentionCounter sdc
LEFT JOIN
[PCSchool].[dbo].[Student] s ON sdc.StudentCode = s.STUDENT#
INNER JOIN
[PCSchool].[dbo].[ALUMREL] ar ON sdc.StudentCode = ar.CHILD#
LEFT JOIN
[PCSchool].[dbo].[IDENTITY] i ON ar.PARENT# = i.[MEMBER#]
LEFT JOIN
[PCSchool].[dbo].[ALUMREL_EX] ax ON ar.parent# = ax.PARENT#
WHERE
(ar.PARENT# <> ar.FAMILY_HASH)
AND ar.EN_EMAIL IN ('I','A')
AND (ax.CORR_PREFERENCE = 1)
AND (sdc.DetentionCount = #DetentionCounter
AND sdc.DetentionType = #DetentionType)
AND (CONVERT(INT, (LTRIM(s.CURRENT_YEAR))) BETWEEN #StartYear AND #EndYear)
ORDER BY
s.SURNAME
END
The command that is executed when I look at SQL Server Profiler is
exec GetCaregiverEmailList #DetentionType='LT',#DetentionCounter=3,#StartYear=9,#EndYear=12
And the following are the rows that are returned if I execute the stored procedure manually or running the above exec command.
Any suggestions or help would be much appreciated.
Regards,
Darren

SqlDbType.Structured to pass Table-Valued Parameters in NHibernate to select without a :param?

I want to pass a collection of IDs (via table-valued parameter) to an NHibernate IQuery select statement to be used in a join:
In native SQL, I can do this (SQLSelectData below). Notice there is no :param in the SqlCommand sql:
public static bool SQLSelectData()
{
string conACME = System.Configuration.ConfigurationManager
.AppSettings["conACME"].ToString();
DataTable tblBusUnit = new DataTable();
tblBusUnit.Columns.Add("VALUE", typeof(int));
DataRow dRow = tblBusUnit.NewRow();
dRow["Value"] = 1;
tblBusUnit.Rows.Add(dRow);
dRow = tblBusUnit.NewRow();
dRow["Value"] = 6;
tblBusUnit.Rows.Add(dRow);
using (SqlConnection con = new SqlConnection(conACME))
{
con.Open();
SqlDataReader rdr;
SqlCommand cmd = new SqlCommand(
"select bus_unit_id, BusUnit " +
"from BusUnit b " +
"join #tvpBusUnit s on s.value = b.BUS_UNIT_ID;",
con);
cmd.Parameters.Add(
new SqlParameter()
{
ParameterName = "#tvpBusUnit",
SqlDbType = SqlDbType.Structured,
TypeName = "dbo.[DLTableTypeInt]",
Value = tblBusUnit
});
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
string stBusUnitId = rdr["bus_unit_id"].ToString();
string strBusUnit = rdr["BusUnit"].ToString();
Console.WriteLine("Bus Unit:" + strBusUnit);
}
}
return true;
}
How do I do this in NHibernate? I tried the accepted solution of this question by using the Sql2008Structured and Structured2008Extensions classes.
See code below that calls the SetStructured():
public void SQLSelectTVP<T>()
{
objNSession = NHibernateHelper.GetCurrentSession(strConn);
DataTable tblBusUnit = new DataTable();
tblBusUnit.Columns.Add("VALUE", typeof(int));
DataRow dRow = tblBusUnit.NewRow();
dRow["Value"] = 1;
tblBusUnit.Rows.Add(dRow);
dRow = tblBusUnit.NewRow();
dRow["Value"] = 6;
tblBusUnit.Rows.Add(dRow);
StringBuilder sbSQL = new StringBuilder();
sbSQL.Length = 0;
sbSQL.Append("select bus_unit_id, Business_Unit " +
"from tblBUSINESS_UNIT b " +
"join #tvpBusUnit s on s.value = b.BUS_UNIT_ID");
IQuery sqlQuery = objNSession.CreateSQLQuery(sbSQL.ToString());
sqlQuery.SetStructured("tvpBusUnit", tblBusUnit);
var lstQR = sqlQuery.List<T>();
}
However, it errors because there is no :param in the SQL:
Parameter tvpBusUnit does not exist as a named parameter in [select bus_unit_id, Business_Unit from tblBUSINESS_UNIT b join #tvpBusUnit s on s.value = b.BUS_UNIT_ID]
How can I fix this?
From the link you posted, I think the way you are accessing the structured variable is incorrect.
s.CreateSQLQuery("EXEC some_sp #id = :id, #par1 = :par1")
.SetStructured("id", dt)
Your code does not use the :id part, that is, :tvpBusUnit.
Also note that the TableType (in TypeName) may have to be created on the DB beforehand. Please check if this is required. From your code:
TypeName = "dbo.[DLTableTypeInt]",
Some discussion on passing table value parameters is provided here but NHibernate has an update without having to create types like this:
Passing table valued parameters to NHibernate. But this may need a pull-request. The answer provided in the other post you referred to allows you to create such types, one for each TableType.

VB.NET and LINQ - Group by in a DataTable

I have a DataTable in VB.NET of this type:
"Yr","Mnth","Period","Amount"
2016, 1, 2016-01, 550.36
2016, 1, 2016-01, 9000.79
2015, 12, 2015-12, 10000.30
2015, 12, 2015-12, 20
What I want to do is to aggregate this data using LINQ like I would in SQL language:
SELECT Yr, Mnth, Period, SUM(Amount) AS Amount
GROUP BY Yr, Mnth, Period;
I have tried to use LINQ in VB.NET but haven't been able to get it right.
Can someone give me some insight?
Thank you.
Dim Amounts As New DataTable 'Your code to load actual DataTable here
Dim amountGrpByDates = From row In Amounts
Group row By dateGroup = New With {
Key .Yr = row.Field(Of Integer)("Yr"),
Key .Mnth = row.Field(Of Integer)("Mnth"),
Key .Period = row.Field(Of String)("Period")
} Into Group
Select New With {
Key .Dates = dateGroup,
.SumAmount = Group.Sum(Function(x) x.Field(Of Decimal)("Amount"))}
I assumed Yr and Mnth to be of type Integer, Period String and Amount Decimal.
Change the types if they differ from yours.
Here's the C# code.
public static class program
{
static void Main(string[] args)
{
try
{
var table = new DataTable();
table.Columns.Add("year", typeof(string));
table.Columns.Add("month", typeof(string));
table.Columns.Add("period", typeof(string));
table.Columns.Add("amount", typeof(decimal));
var row = table.NewRow();
table.Rows.Add(row);
row["year"] = "2015";
row["month"] = "Jan";
row["period"] = "Period1";
row["amount"] = 100;
row = table.NewRow();
table.Rows.Add(row);
row["year"] = "2015";
row["month"] = "Jan";
row["period"] = "Period1";
row["amount"] = 50;
row = table.NewRow();
table.Rows.Add(row);
row["year"] = "2016";
row["month"] = "Fed";
row["period"] = "Period2";
row["amount"] = 5.55;
var result = (from r in table.AsEnumerable()
group r by new
{
Year = r.Field<string>("year"),
Month = r.Field<string>("month"),
Period = r.Field<string>("period"),
} into grp
select new {
grp.Key,
total = grp.Sum(p=> p.Field<decimal>("amount"))
});
foreach(var grp in result)
{
Console.WriteLine("{0} {1} {2} = {3}", grp.Key.Year, grp.Key.Month, grp.Key.Period, grp.total);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}

ASP.Net MVC Passing array value to database table columns

I used the code from http://arranmaclean.wordpress.com/2010/07/20/net-mvc-upload-a-csv-file-to-database-with-bulk-upload/#comment-188 to upload, read and insert to DB the csv file. My problem now is how can I pass the values from the csv file to the specific database table columns.
string Feedback = string.Empty;
string line = string.Empty;
string[] strArray;
DataTable dt = new DataTable();
DataRow row;
Regex r = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
StreamReader sr = new StreamReader(fileName);
line = sr.ReadLine();
strArray = r.Split(line);
Array.ForEach(strArray, s => dt.Columns.Add(new DataColumn()));
while ((line = sr.ReadLine()) != null)
{
row = dt.NewRow();
row.ItemArray = r.Split(line);
dt.Rows.Add(row);
}
and ...
private static String ProcessBulkCopy(DataTable dt)
{
string Feedback = string.Empty;
string connString = ConfigurationManager.ConnectionStrings["DataBaseConnectionString"].ConnectionString;
using( SqlConnection conn = new SqlConnection(connString))
{
using (var copy = new SqlBulkCopy(conn))
{
conn.Open();
copy.DestinationTableName = "BulkImportDetails";
copy.BatchSize = dt.Rows.Count;
try
{
copy.WriteToServer(dt);
Feedback = "Upload complete";
}
catch (Exception ex)
{
Feedback = ex.Message;
}
}
}
return Feedback;
}
Below are my sample contents:
08/01/12,05:20:12 AM,243752,,South Lobby3,522557,IN
08/01/12,05:26:03 AM,188816,,North Lobby1,358711,IN
My DB table columns:
empno | date | time
I only need to insert the first three arrays.. (e.g. 08/01/12,05:20:12 AM,243752) and proceed to the next row to insert it again to its specified columns. My csv file doesn't have headers. I saw a code about passing the array values but it requires headers. How can I pass the values even without having a header in my csv file? Please help me guys.. Thank you..