I have a problem that doesn't appear always, but it do it most of the times. In my huge java forecast class I have some ResultSets, and when I execute the routine I get:
com.microsoft.sqlserver.jdbc.SQLServerException: El nombre de columna DistanciaMision no es vßlido.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:170)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.findColumn(SQLServerResultSet.java:626)
at com.microsoft.sqlserver.jdbc.SQLServerResultSet.getString(SQLServerResultSet.java:2301)
at es.csic.iiia.udt.itim.iInformation.WebData.Forecast.etaMSR(Forecast.java:1109)
at es.csic.iiia.udt.itim.iInformation.WebData.Forecast.phase2(Forecast.java:662)
at es.csic.iiia.udt.itim.iInformation.WebData.Forecast.setData(Forecast.java:166)
at es.csic.iiia.udt.itim.iInformation.WebData.Forecast.main(Forecast.java:81)
at es.csic.iiia.udt.itim.iInformation.WebData.Forecast.execute(Forecast.java:71)
at org.quartz.core.JobRunShell.run(JobRunShell.java:199)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:546)
The column exists, so I don't know what is the problem...
The code line is this one:
Float distancia_restante = (float) ( Integer.parseInt(rs.getString("DistanciaMision")) - (myodometer - initialodometer));
The same problem appears on other columns but it usually crash here.
Thank you!
Edit: ok, this is the whole method:
private static void etaMSR() throws Exception, SQLException {
/**
*
* Calculem ETAN MSR - Mision - Seguimiento - Restricciones conductor
*
*
**/
System.out
.print("Get data from iTIM forecast&forecastAUX DDBB ....... ");
myStatement = MSSQLServerAccess.connection();
// Distancia mision, ruta, hora mision anterior, hora
rs = getTable("SELECT dbo.WebForecast.IdConductor, dbo.WebForecast.IdMision, dbo.WebForecast.IdMisionAnterior, dbo.WebForecast.DistanciaMision, "
+ " WebForecast_1.HoraIniMis AS himanterior, dbo.WebForecast.HoraFiMis AS hfmactual, WebForecast_1.Ciudad AS CiudadOrigen,"
+ " dbo.WebForecast.Ciudad AS CiudadDestino, dbo.Distancias.Ruta, dbo.WebForecast.HoraDistancia AS HoraDistancia"
+ " FROM dbo.WebForecast AS WebForecast_1 INNER JOIN"
+ " dbo.Distancias ON WebForecast_1.Ciudad = dbo.Distancias.Origen RIGHT OUTER JOIN"
+ " dbo.WebForecast ON WebForecast_1.IdMision = dbo.WebForecast.IdMisionAnterior AND dbo.Distancias.Destino = dbo.WebForecast.Ciudad"
+ " WHERE (dbo.WebForecast.IdConductor <> '') AND (CONVERT(datetime, '"
+ df.format(fechaDia)
+ "') <= dbo.WebForecast.HoraFiMis) "
+ " AND WebForecast_1.HoraIniMis <= CONVERT(datetime, '"
+ df.format(fechaDia) + "') ");
System.out.println("[ok]");
while (rs.next() && (rs.getString("IdConductor") != "") && org.apache.commons.lang.StringUtils.isNumeric(rs.getString("IdConductor"))) {
int initialodometer = 0;
String start = null;
if (rs.getString("HoraDistancia") != null) {
start = rs.getString("HoraDistancia");
}
if (rs.getString("himanterior") != null) {
start = rs.getString("himanterior");
}
if (start != null) {
ResultSet myrs = null;
Timestamp tobjetivo = rs.getTimestamp("himanterior");
long boundtime = 7200000; // 3600000 = 60m = 1h
Timestamp tini = (Timestamp) rs.getTimestamp("himanterior")
.clone();
Timestamp tfin = (Timestamp) rs.getTimestamp("himanterior")
.clone();
tini.setTime(tini.getTime() - boundtime);
tfin.setTime(tfin.getTime() + boundtime);
int contador = 0;
long bestdiff = 0;
myStatement = MSSQLServerAccess.connection();
myrs = getTable("SELECT DISTINCT Odometer, DT "
+ "FROM DriverEvents "
+ "WHERE (DT BETWEEN CONVERT(datetime, '"
+ df.format(tini) + "') " + "AND CONVERT(datetime, '"
+ df.format(tfin) + "')) " + "AND (CardId = '"
+ Integer.parseInt(rs.getString("IdConductor")) + "')");
int j = 0;
while (!myrs.next() && (j < 20)) {
// En caso de no encontrar en las 2h antes y despues nada:
tini.setTime(tini.getTime() - boundtime);
tfin.setTime(tfin.getTime() + boundtime);
myrs.close();
myStatement = MSSQLServerAccess.connection();
myrs = getTable("SELECT DISTINCT Odometer, DT "
+ "FROM DriverEvents "
+ "WHERE (DT BETWEEN CONVERT(datetime, '"
+ df.format(tini) + "') "
+ "AND CONVERT(datetime, '" + df.format(tfin)
+ "')) " + "AND (CardId = '"
+ Integer.parseInt(rs.getString("IdConductor"))
+ "')");
j++;
}
if (myrs.next()) {
initialodometer = myrs.getInt("Odometer");
bestdiff = Math.abs(tobjetivo.getTime()
- myrs.getTimestamp("DT").getTime());
contador++;
while (myrs.next()) {
long pretendiente = Math.abs(tobjetivo.getTime()
- myrs.getTimestamp("DT").getTime());
if (pretendiente <= bestdiff) {
bestdiff = pretendiente;
initialodometer = myrs.getInt("Odometer");
}
contador++;
}
}
myrs.close();
}
// Get Odometer distance at the moment
if (!rs.getString("IdConductor").isEmpty() && !rs.getString("IdConductor").equals("") ) {
ResultSet myrs = null;
int myodometer = 0;
myStatement = MSSQLServerAccess.connection();
myrs = getTable("SELECT MAX(DT) AS DT, MAX(Odometer) AS Odometer"
+ " FROM dbo.DriverEvents"
+ " WHERE (CardId = '"
+ Integer.parseInt(rs.getString("IdConductor"))
+ "') AND (DT > CONVERT(datetime, '"
+ df.format(fechaDatos) + "')) ");
if (myrs.next()) {
myodometer = myrs.getInt("Odometer");
if (initialodometer == 0)
initialodometer = myodometer;
Float distancia_restante = (float) ( Integer.parseInt(rs.getString("DistanciaMision")) - (myodometer - initialodometer));
if (distancia_restante < 0)
distancia_restante = (float) 0;
Timestamp ETAN = null;
Calendar cal = Calendar.getInstance();
if (rs.getTimestamp("himanterior") != null && rs.getTimestamp("himanterior").toString() != "") {
cal.setTimeInMillis(rs.getTimestamp("himanterior")
.getTime());
if (cal.after(Calendar.getInstance())) {
cal.setTimeInMillis(rs.getTimestamp("himanterior")
.getTime());
}
if (cal.before(Calendar.getInstance())) {
cal = Calendar.getInstance();
}
} else {
if (rs.getTimestamp("HoraDistancia") != null)
cal.setTimeInMillis(rs
.getTimestamp("HoraDistancia").getTime());
}
myStatement = MSSQLServerAccess.connection();
rs2 = getTable("SELECT TOP (100) PERCENT CardId, DT"
+ " FROM dbo.DriverEvents"
+ " GROUP BY CardId, DT"
+ " HAVING (CardId = '"
+ Integer.parseInt(rs.getString("IdConductor"))
+ "') AND (DT > CONVERT(datetime, '"
+ df.format(fechaDatos) + "'))");
if (rs2.next()) {
ETAN = getETAN(rs, distancia_restante, cal);
} else {
ETAN = getETA(rs, distancia_restante, cal, 1);
Statement myStatement2 = MSSQLServerAccess.connection();
myStatement2.executeUpdate("UPDATE WebForecast "
+ "SET ETAmsr = '" + df.format(ETAN)
+ "', KmsDiff = '" + distancia_restante.intValue()
+ "' " + "WHERE IdMision = '"
+ rs.getString("IdMision") + "'");
} else {
}
}
}
rs.close();
}
And the statement, maybe i'm doing something wrong?:
private static Statement conStatement(Properties properties){
String driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; // Load the JDBC driver
String dbURL = "jdbc:sqlserver://"
+ properties.getProperty("qualcomm.action.JDBC.MSSQLServerAccess.ddbbserverIP")
+ ";DatabaseName="
+ properties.getProperty("qualcomm.action.JDBC.MSSQLServerAccess.ddbbName")
+ ";SelectMethod=Cursor;"; // Connect to a server and database
String userName = properties.getProperty("qualcomm.action.JDBC.MSSQLServerAccess.userName");
String userPwd = properties.getProperty("qualcomm.action.JDBC.MSSQLServerAccess.userPwd");
Connection dbConn;
try {
Class.forName(driverName);
dbConn = DriverManager.getConnection(dbURL, userName, userPwd);
//log.info("Connection Successful!");
Statement myst = dbConn.createStatement();
return myst;
} catch (Exception e) {
log.error(e);
System.out.println(e);
return null;
}
}
Thanks guys :) Could be something wrong with the statement?
remember that Java is case-sensitive and so can be your table on SQL depending on the way you created them, actually depending on the collation on your DB. If your database is created with a Case Sensitive collation then all object names will be Case Sensitive.
try to check the exact columns name of the column on SQL and access it using [] and the exact case
Related
public static boolean CheckIsDataAlreadyInDBorNot(String TableName,
String dbfield, String fieldValue) {
SQLiteDatabase sqldb = EGLifeStyleApplication.sqLiteDatabase;
String Query = "Select * from " + TableName + " where " + dbfield + " = " + fieldValue;
Cursor cursor = sqldb.rawQuery(Query, null);
if(cursor.getCount() <= 0){
cursor.close();
return false;
}
cursor.close();
return true;
}
I already created a test class, simple test class, but I cant give data to it, Somebody can explain me a little please here is my code, when i Run the test the cover is 14 % and I dont know how to give data, for exceptions and made it at leas the 75 %
public void cargaPacientes () {
lMSD = new List<Enrollee__c>();
bLista = true;
String strCredencial = '';
String strPoliza = '';
String strCertificado = '';
String strRfc = '';
String fNacimiento = '';
String nombres = '';
String Aseguradora = '';
String Contratante = '';
String query = '';
Boolean correcto = true;
integer cuentacriterios = 0;
string producto = '';
if (proveedor.Tipo_de_Proveedor__c == 'Dentista' || proveedor.Tipo_de_Proveedor__c == 'Clínica' || proveedor.Tipo_de_Proveedor__c == 'Hospital'){
producto = 'Dental';
}else if (proveedor.Tipo_de_Proveedor__c == 'Óptica'){
producto = 'Visión';
}
if((msd.DENTEGRA_ID_Number__c != null) && (msd.DENTEGRA_ID_Number__c != '')) {
strCredencial = ' and DENTEGRA_ID_Number__c like \'' + msd.DENTEGRA_ID_Number__c + '\'';
System.debug(':::: strCredencial = ' + strCredencial);
cuentacriterios = cuentacriterios + 1;
}
if((msd.Family_Number__c != null) && (msd.Family_Number__c != '')){
strCertificado = ' and Family_Number__c like \'' + msd.Family_Number__c + '\'';
System.debug(':::: strCertificado = ' + strCertificado);
cuentacriterios = cuentacriterios + 1;
}
if((msd.RFC__c != null) && (msd.RFC__c != '')){
strRfc = ' and RFC__c like \'%' + msd.RFC__c + '%\'';
System.debug(':::: strRfc = ' + strRfc);
cuentacriterios = cuentacriterios + 1;
}
if((msd.Policy_Number__c != null) && (msd.Policy_Number__c != '')){
strPoliza = ' and Policy_Number__c like \'%' + msd.Policy_Number__c + '%\' ';
System.debug(':::: strPoliza = ' + strPoliza);
cuentacriterios = cuentacriterios + 1;
}
if(msd.Birth_Date__c != null) {
fNacimiento = ' and Birth_Date__c = ' + String.valueOf(msd.Birth_Date__c);
System.debug(':::: fNacimiento = ' + fNacimiento);
cuentacriterios = cuentacriterios + 1;
}
if(msd.Name != null) {
nombres = ' and Name like \'%' + msd.Name + '%\' ';
System.debug(':::: nombres = ' + nombres);
cuentacriterios = cuentacriterios + 1;
}
if(msd.Contratante__c != null) {
Contratante = ' and Contratante__c like \'%' + msd.Contratante__c + '%\' ';
System.debug(':::: Contratante = ' + Contratante);
cuentacriterios = cuentacriterios + 1;
}
if(msd.Aseguradora__c != null) {
Aseguradora = ' and Aseguradora__c like \'%' + msd.Aseguradora__c + '%\' ';
System.debug(':::: Aseguradora = ' + Aseguradora);
cuentacriterios = cuentacriterios + 1;
}
//if(strCredencial != '' || strCertificado != '' || strRfc != '' || strPoliza != '' || fNacimiento != '' || nombres != '') {
if(cuentacriterios>1){
//query = 'Select e.Contact__c, e.Id, e.Name, e.Policy_Number__c, e.Family_Number__c, e.RFC__c, e.Birth_Date__c from Enrollee__c e where Cve_tipo_registro__c = \'Elegibilidad\' and OwnerId = \'' + userID + '\'' + strCredencial + strCertificado + strRfc + strPoliza + fNacimiento;
query = 'Select e.Contact__c, e.Id, e.Name, e.Policy_Number__c, e.Family_Number__c, e.RFC__c, e.Birth_Date__c, e.Plan__c,Product__c from Enrollee__c e where Cve_tipo_registro__c = \'Elegibilidad\' and Enrollee_Status__c = \'Elegible\' and Product__c = \'' + producto + '\'' + strCredencial + strCertificado + strRfc + strPoliza + fNacimiento + nombres + Contratante + Aseguradora;
System.debug(':::: query concatenado = ' + query);
lMSD = Database.query(query);
cuentacriterios = 0;
} else {
System.debug(':::: Sin criterios');
bLista = false;
correcto = false;
cuentacriterios = 0;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO,'Debe filtrar al menos por dos criterios.'));
}
if(lMSD.size() == 0 && correcto == true) {
bLista = false;
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO,'No se obtuvieron resultados basado en sus criterios de búsqueda. Utilice un criterio diferente o comuníquese al Centro de Contacto para confirmar elegibilidad.'));
msd = new Enrollee__c();
}
if(lMSD.size() > 0) {
ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM,'Se encontraron ' + lMSD.size() + ' registros. Favor de seleccionar el registro que corresponda con el nombre de su paciente.'));
msd = new Enrollee__c();
}
here is My test Class
private static void cargaPacientesTesting(){
Test.startTest();
PortalProveedoresController obj = new PortalProveedoresController();
obj.cargaPacientes();
Test.stopTest();
}
Thank you Im stuck with this, thanks
im getting data from the server as expected as you can see here (the data is not null)
but it won't enter to while (reader.Read())
or sometimes after one or two iteration im getting the exception
"Data is Null. This method or property cannot be called on Null values."
again, the data is not null
EDIT: added some code snippet
System.Data.SqlClient.SqlConnection sqlConnection = null;
try
{
sqlConnection = connectToDB();
SqlCommand cmd = new SqlCommand(#"SELECT TOP 50 R.[RoundID] ,[DailyOrder] ,min(R.[RoundName]) as RoundName, min([EquipCode]) as TruckCode,
sum(RD.[Weight]) as [Weight], RD.BlilCode, min(Blil.BlilName) as BlilName
FROM [CVfeedDB].[dbo].[Planning.Rounds] as R
left join [CVfeedDB].[dbo].[Planning.RoundsDetail] as RD on R.RoundID = RD.RoundID
left join [CVfeedDB].[dbo].[constants.Blil] as Blil on RD.BlilCode = Blil.BlilCode
WHERE R.[ActionDate] = #ActionDate
Group by R.[RoundID] ,[DailyOrder], RD.BlilCode
order by [DailyOrder] ", sqlConnection);
cmd.CommandType = System.Data.CommandType.Text;
//string date = Convert.ToString();
var dt = DateTime.ParseExact(Variables().Item("Date Select").get_Value(0).ToString(), "dd/MM/yyyy", null);
var dt1 = dt.Date.ToString("yyyy-MM-dd");
cmd.Parameters.AddWithValue("#ActionDate",dt1 );
string prefix = "";
int i = 1;
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
prefix = ordersName + i.ToString() + "]";
List<object> list = new List<object>();
List<object> IDList = new List<object>();
int id = Convert.ToInt32(Variables().Item(prefix + ".LoopID").get_Value(0));
int k = reader.GetInt32(0);
if (id == 0 || id == k)//if no id or we are writing the same id
{
Variables().Item(prefix + ".LoopID").set_Value(0, reader.GetInt32(0));
//Variables().Item(prefix + ".").set_Value(0, reader.GetInt32(1)); //Order sequence
Variables().Item(prefix + ".LoopName").set_Value(0, reader.GetString(2));
Variables().Item(prefix + ".Truck").set_Value(0, Convert.ToInt32(reader.GetString(3)));
Variables().Item(prefix + ".Weight").set_Value(0, Convert.ToInt32(reader.GetDecimal(4)));
Variables().Item(prefix + ".MixID").set_Value(0, Convert.ToInt32(reader.GetString(5)));
Variables().Item(prefix + ".MixName").set_Value(0, reader.GetString(6));
}
please not that Variables().Item(...) it how I communicate with 3rd party software
First problem is that your SqlConnection is null. It will always return null value.
Secondally
You should check the reader has rows like i m using reader.Hasrows
System.Data.SqlClient.SqlConnection sqlConnection = null;
try
{
sqlConnection = connectToDB();
SqlCommand cmd = new SqlCommand(#"SELECT TOP 50 R.[RoundID] ,[DailyOrder] ,min(R.[RoundName]) as RoundName, min([EquipCode]) as TruckCode,
sum(RD.[Weight]) as [Weight], RD.BlilCode, min(Blil.BlilName) as BlilName
FROM [CVfeedDB].[dbo].[Planning.Rounds] as R
left join [CVfeedDB].[dbo].[Planning.RoundsDetail] as RD on R.RoundID = RD.RoundID
left join [CVfeedDB].[dbo].[constants.Blil] as Blil on RD.BlilCode = Blil.BlilCode
WHERE R.[ActionDate] = #ActionDate
Group by R.[RoundID] ,[DailyOrder], RD.BlilCode
order by [DailyOrder] ", sqlConnection);
cmd.CommandType = System.Data.CommandType.Text;
//string date = Convert.ToString();
var dt = DateTime.ParseExact(Variables().Item("Date Select").get_Value(0).ToString(), "dd/MM/yyyy", null);
var dt1 = dt.Date.ToString("yyyy-MM-dd");
cmd.Parameters.AddWithValue("#ActionDate",dt1 );
string prefix = "";
int i = 1;
SqlDataReader reader = cmd.ExecuteReader();
if(reader.HasRows)
{
while (reader.Read())
{
prefix = ordersName + i.ToString() + "]";
List<object> list = new List<object>();
List<object> IDList = new List<object>();
int id = Convert.ToInt32(Variables().Item(prefix + ".LoopID").get_Value(0));
int k = reader.GetInt32(0);
if (id == 0 || id == k)//if no id or we are writing the same id
{
Variables().Item(prefix + ".LoopID").set_Value(0, reader.GetInt32(0));
//Variables().Item(prefix + ".").set_Value(0, reader.GetInt32(1)); //Order sequence
Variables().Item(prefix + ".LoopName").set_Value(0, reader.GetString(2));
Variables().Item(prefix + ".Truck").set_Value(0, Convert.ToInt32(reader.GetString(3)));
Variables().Item(prefix + ".Weight").set_Value(0, Convert.ToInt32(reader.GetDecimal(4)));
Variables().Item(prefix + ".MixID").set_Value(0, Convert.ToInt32(reader.GetString(5)));
Variables().Item(prefix + ".MixName").set_Value(0, reader.GetString(6));
}
}
}
try this.
string namethestore = myReader.IsDBNull(namePos)
? string.Empty
: reader.GetString(reader.GetString(2));
Variables().Item(prefix + ".LoopName").set_Value(0, namethestore);
I have added isNull(rowname, 0 ) to the problematic rows and it solved my problem
My function: Removes the unit in a specific row of a given Table
private static void removeUnits(String connectionString, String tableName, String columnID, String columnToFix)
{
List<String> rowsToEdit = new List<String>();
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT " + columnID + "," + columnToFix + " FROM " + tableName;
connection.Open();
using (var reader = command.ExecuteReader())
{
var indexOfR_MEASUREDVALUEID = reader.GetOrdinal(columnID);
var indexOfT_VALUE = reader.GetOrdinal(columnToFix);
while (reader.Read())
{
var t_value = reader.GetValue(indexOfT_VALUE);
var t_id = reader.GetValue(indexOfR_MEASUREDVALUEID);
String newValue = getWithoutUnit(t_value.ToString());
if (newValue != null)
{
String sql = "UPDATE " + tableName + " SET " + columnToFix + "='" +
newValue + "' WHERE " + columnID + "='" + t_id + "';";
rowsToEdit.Add(sql);
}
}
connection.Close();
}
}
Console.WriteLine("start writing " + rowsToEdit.Count + " entries?");
Console.ReadLine();
SqlCommand sqlCmd;
sqlCmd = new SqlCommand("", connection);
sqlCmd.Connection.Open();
foreach (String command in rowsToEdit)
{
sqlCmd.CommandText = command;
sqlCmd.ExecuteNonQuery();
}
}
Console.WriteLine(rowsToEdit.Count + " commands executed");
}
I am using C# in Visual Studio 2010 and SQL-Server 2012.
It works fine, but executing of 200000 lines takes really long.
Is its possible to do this faster?
My suggestion involves looking into parallelism:
Note: The code isn't tested, just typed it out in Notepad++
private static void removeUnits(String connectionString, String tableName, String columnID, String columnToFix)
{
List<new Tuple<object, object>> rowsToEdit = new List<new Tuple<object, object>>();
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (var command = connection.CreateCommand())
{
command.CommandText = "SELECT " + columnID + "," + columnToFix + " FROM " + tableName;
connection.Open();
using (var reader = command.ExecuteReader())
{
var indexOfR_MEASUREDVALUEID = reader.GetOrdinal(columnID);
var indexOfT_VALUE = reader.GetOrdinal(columnToFix);
while (reader.Read())
{
rowsToEdit.Add(new Tuple<object, object>(reader.GetValue(indexOfT_VALUE),reader.GetValue(indexOfR_MEASUREDVALUEID)));
}
connection.Close();
}
}
}
// Use parallelism here
Parallel.Foreach(rowsToEdit, currentRow =>
{
String newValue = getWithoutUnit(currentRow.Value1.ToString());
if (newValue != null)
{
// reopen connection
// use parameters here, and call SP
}
}
Console.WriteLine("start writing " + rowsToEdit.Count + " entries?");
Console.ReadLine();
}
Stored Proc:
Create StoredProcedure MySP
(
#tablename varchar(50),
#columnToFix varchar(50),
#newValue varchar(50),
#columnID varchar(50),
#tID varhcar(varchar(50)
)
As
Begin
Declare #MySQL varchar(500)
Set #MySQL = 'Update ' + #tableName + ' Set ' + #columnToFix + ' = '' + #newValue + ''' + ' Where ' + #columnID + ' = '' + #tID + '''
sp_executesql #MySQL
End
It's important to note that dynamic sql is generally frowned down upon. Here's a link discussing dynamic sql (pros/cons):http://www.sommarskog.se/dynamic_sql.html
Also it's possible you may run into some locking/contention issues b/c you're hitting one table(based on the input parameters of the function).
First try to use Parameters as already mentioned in the comments. Second, use the SqlCommand.Prepare() statement. The actual speed also depends on your machine capacities (HD Write Speed/RAM). Here is the example (you may have to edit the SqlDbTypes according to your Colum Types)
private static void RemoveUnits(string connectionString, string tableName, string columnID, string columnToFix)
{
Dictionary<int, string> rowsToEdit = new Dictionary<int, string>();
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT " + columnID + "," + columnToFix + " FROM " + tableName;
using (var reader = command.ExecuteReader())
{
var indexOfR_MEASUREDVALUEID = reader.GetOrdinal(columnID);
var indexOfT_VALUE = reader.GetOrdinal(columnToFix);
while (reader.Read())
{
string t_value = reader.GetString(indexOfT_VALUE);
int t_id = reader.GetInt32(indexOfR_MEASUREDVALUEID);
string newValue = getWithoutUnit(t_value);
if (newValue != null)
{
// save values in dictionary
rowsToEdit[t_id] = newValue;
}
}
}
}
Console.WriteLine("start writing " + rowsToEdit.Count + " entries?");
Console.ReadLine();
string updateCmd = "UPDATE " + tableName + " SET " + columnToFix + "= #Value WHERE " + columnID + "= #Key;";
using (SqlTransaction transaction = connection.BeginTransaction())
{
SqlCommand sqlCmd = connection.CreateCommand();
sqlCmd.CommandText = updateCmd;
sqlCmd.Parameters.Add("#Value", System.Data.SqlDbType.NVarChar, -1);
sqlCmd.Parameters.Add("#Key", System.Data.SqlDbType.Int);
// important for performance
sqlCmd.Prepare();
foreach (var update in rowsToEdit)
{
// change values of parameters
sqlCmd.Parameters["#Key"].Value = update.Key;
sqlCmd.Parameters["#Value"].Value = update.Value;
// and execute it
sqlCmd.ExecuteNonQuery();
}
transaction.Commit();
}
}
Console.WriteLine(rowsToEdit.Count + " commands executed");
}
Edit: if getWithoutUnit(string) does something not very complex, you could probably do your operation with a single statement using TSQL, which comes with various string manipulation capabilities. Like UPDATE TableName SET StringColumn = <string manipulation TSQL here>, see http://msdn.microsoft.com/en-us/library/ms181984.aspx
Edit2: added transaction from comment hint (indeed should be faster as well), strongly typed columns
I'm getting the error:-
error: cannot find symbol
tofile.println("Dancing" + " " + danceminutes + " " + bpm);
^
symbol: variable tofile
location: class CreateFile
I'm not sure why.
// writing to a file
PrintWriter toFile = new PrintWriter(new FileWriter("exLog.txt"));
Random randy = new Random();
int count = randy.nextInt(12) + 19;
for (int i = count; i > 0; i--) {
int exercise = randy.nextInt(3);
if (exercise == 0) {
int minutesOne = randy.nextInt(47) + 14;
int minutesTwo = randy.nextInt(62) + 59;
int minutesThree = randy.nextInt(122) + 119;
int roulette = randy.nextInt(100);
if (roulette <= 74) {
int runoneminutes = minutesOne;
double speed = 4.9 + (16.1 - 4.9) * randy.nextDouble();
double distance = speed * runoneminutes/60;
tofile.println("Running" + " " + runoneminutes + " " + distance);
}
else if (roulette > 74 && roulette < 96) {
int runtwominutes = minutesTwo;
double twospeed = 4.9 + (16.1 - 4.9) * randy.nextDouble();
double twodistance = twospeed * runtwominutes/60;
tofile.println("Running" + " " + runtwominutes + " " + twodistance);
}
else if (roulette >= 96) {
int runthreeminutes = minutesThree;
double threespeed = 4.9 + (16.1 - 4.9) * randy.nextDouble();
double threedistance = threespeed * runthreeminutes/60;
tofile.println("Running" + " " + runthreeminutes + " " + threedistance);
}
}
if (exercise == 1) {
int bikeminutesOne = randy.nextInt(62) + 29;
int bikeminutesTwo = randy.nextInt(212) + 89;
int bikeroulette = randy.nextInt(100);
if (bikeroulette <= 49) {
int bikeoneminutes = bikeminutesOne;
double bikeonespeed = 7.9 + (25.1 - 7.9) * randy.nextDouble();
double bikeonedistance = bikeonespeed * bikeoneminutes/60;
tofile.println("Biking" + " " + bikeoneminutes + " " + bikeonedistance);
}
else if (bikeroulette > 49) {
int biketwominutes = bikeminutesTwo;
double biketwospeed = 7.9 + (25.1 - 7.9) * randy.nextDouble();
double biketwodistance = biketwospeed * biketwominutes/60;
tofile.println("Biking" + " " + biketwominutes + " " + biketwodistance);
}
}
if (exercise == 2) {
int exercises = randy.nextInt(15) + 1;
int reps = randy.nextInt(37) + 9;
double liftminutes;
int liftminutes = 5*reps*exercises/60 + 2*(exercises-1);
tofile.println("Lifting" + " " + liftminutes + " " + reps);
}
if (exercise == 3) {
int danceminutes = randy.nextInt(90) + 29;
double bpm = 79.9 + (220 - 79.9) * randy.nextDouble();
tofile.println("Dancing" + " " + danceminutes + " " + bpm);
}
}
toFile.close(); //saving output file
} // end main
} // end CreateFile class
The variable name is toFile. The compiler is complaining about the use of 'tofile'.