I need to dynamically build a control file for a SQL loader but when tokenizing line values read from a file i am unable to work/assign the last value to a variable even though i can print the actual token value while in the loop.
Below is the code snippet i have and would appreciate all the help i can get:
//headElement declared as headElement[42]
//getCol function is used to decode column keys present in line being read
istringstream ss(line);
Alas, that's not quite enough information to help. Could you make a small program (complete with main() that compiles) that reproduces the problem?
Usually the cause of such things is a mismatch between attempts to read from file, action taken when the file is correctly read, and the condition that notices failed attempts.
Another thing that catches my eye is the way you are handling 'arrayCountHeader' -- I'm not sure what you are trying to do with it or how the size of your 'headElement' array has anything to do with it...
One other issue is the fact that you are repeatedly opening and closing a file to append a small chunk of data to it at a time. Don't do that. Open your file before any handling loop, process your data and append to it, then close it. Any external process waiting on the file will get the data quickly enough. (More quickly, actually.)
Thanks for the reply here's the updated code including main and minimize the open and closing of the file being worked with (please note there are two files one for reading data and the other for writing a temp file):
}
}
}
wfile.close();
ofile.close();
}
else cout << "Unable to open file";
return 0;
}
As for the first question i'm using 'arrayCountHeader' to assign each token read to the array as well as validate the next item in the array against the array size while in the loop.
Before we go further, I'm pretty sure either I'm missing something important or you are.
Given a file with those number, you need to convert those number into things like "PLATFORM_MODEL"? (Because that's what it looks like you are trying to do.)
Typically a database will dump a fixed-format CSV file. Each column represents a value. So the "PLATFORM_MODEL" column will contain the numbers (or whatever the ID string is) for the "platform model" associated with the record.
You've got to create a SQL query that does what? Selects certain columns?
The purpose of the exercise is to create a SQL Loader control file to be able to insert data to the database. So whats present in the file is a bunch of numbers that needs to be decoded based on the specification given by the vendor.
Whats not present in the dummy file i gave was the actual data (the numbers you are referring to)
Almost. So your input file is just a single record, containing the vendor-specific numbers that represent column values, and you want to turn that into a single SQL*Loader control file?
What's special about line 2 of your input data?
Sorry to keep asking so many dumb questions, but your (non-functional) code only helped so much.
The huge if..else if... statement needs to be simplified. If you plan to reuse this program, the data encoded in that statement should be a file itself, which you can load into a std::map <unsigned, string>. Then your input file (the one with all the numbers) will parameterize the map to produce the FILE LOAD.
bool write_control_file(
ofstream& f, // f will have to have already been opened for writing
const string& control, // the string with vendor numbers (that you read from your input file)
const string& table_name, // the name of the table to manipulate with this control file
const lookup_type& lookup ) // our vendor code lookup table
{
f << "LOAD DATA\n""INFILE *\n""APPEND INTO TABLE " << table_name << "\n""FIELDS TERMINATED BY ','\n""(\n";
istringstream ss( control );
string s;
while (getline( ss, s, ',' ))
{
istringstream ss( s );
unsigned code;
ss >> code;
if (!ss.eof()) returnfalse; // file is corrupt!
if (map.count( code ) != 1)
f << "UNKNOWN,\n"; // or however you wish to handle this error
else
f << map[ code ] << ",\n";
}
f << "FILENAME\n"")\n""BEGINDATA\n";
returntrue;
}
The structure of this code is to maintain flexibility and make it easy to handle changes.