I'm working on an old legacy system. It breaks all kinds of rules from normalization to common sense, but alas I'm stuck with it. That being said here it goes.
Question:
How would I append a name to a field without getting rid of the existing names in that field? Also, how do I do this over and over again? Same name for the appending, but different names that I need to keep intact that are unique to each row in the database.
Example: Rows as they are in the name column:
"Donnie/Mike/Daniel"
"Donnie/James"
"Steve"
Example: Rows after the script in the name colum:
"Donnie/Mike/Daniel/Dee"
"Donnie/James/Dee"
"Steve/Dee"
I'm thinking SQL will not be enough here and I'll have to write a script. What does SO think? Besides the usual sickening feeling you naturally get from legacy apps.
Here is the syntax in SQL Server:
update table
set field = field+'/'+<newval>
where <i want the new val>
In other databases, the concatenation operation might be:
set field = field || '/' ||
set field = concat(field, '/', )
Related
So I've got a field in my database that will contain serial id numbers separated by commas eg. 2817,2385,4937,3298 I want to be able to add more numbers to the same field over time.
The best way I can think to do this is to get the contents, add the new numbers to it, and insert them back into the database.
What I'm wondering is if there's a more direct way. I had trouble thinking of a good way to word this that yields helpful search results so I'm asking here.
Yes there is.
UPDATE `table` SET `column` = CONCAT(`column`,',new_serial')
However this is not right, you should never store comma separated values. It's called database normalization.
Try this:
UPDATE `tableName` SET `yourColum` = CONCAT(`yourColumn`, ',nextId')
This will update your column as you requested.
I am downloading new csv's each night using a cron job with PHP. Each csv is normally about the same, possibly one night within a month a field is new. I need to get the new field and append it to the database. I don't know how to get the type of the new field. I saw someone else's question with gettype() but i'm not sure if that would work or not since the data is inside a csv so wouldn't they all be strings when some need to be floats, or ints? How would I go across checking the type?
The second question, is there a way to check if there is not a name inside of a table? For instance, if they add a new field called foo52, and I have foo1 through foo51 in my database, is there a quick way to search for fields that aren't there, or would I have to use a select statement for each one and append it when it's false?
I use MySQL for my database.
Thanks for your help.
The first question on the part about getting the type is the simply try the conversion of the data itself and then seeing if the data is equivalent with a == comparison.
So,
some,data,is,123
After reading in the data you can then try the conversion to various types such as strings, ints, ect...then from that you are able to determine the type of the data.
For the second question you can get the column names by doing:
show columns from db.table_name
Then you can do a simple in_array to test if the new column name is already in the database.
EDIT:
Using array_diff can simplify the finding of the missing/new column names from the CSV.
csv_names = get_csv_column_names();
sql_names = get_sql_column_names();
new_names = array_diff( csv_names, sql_names );
I have found the parsecsv-for-php library very handy for [re|de]constructing CSV data.
For the first question: you can test if it's numeric with is_numeric(). If not, store as string. If yes, create the field as numeric in your database. If you want, you can use regex to check if it's a date or some other datatype you think is required to be stored correctly (i.e. not a a default-text)
for the second question: getting the fieldnames of a table in Postgres is done with the follwoing query
$sql = "SELECT attname FROM pg_catalog.pg_attribute
WHERE attrelid =
(SELECT c.oid FROM pg_catalog.pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = '$this->tableName' AND n.nspname = 'public')
AND attnum > 0
AND NOT attisdropped";
For MySQL, it should be doable with "show columns from db.table_name".
Once you have the fields, use in_array() to check if it exists already...
Note that: you'd probably need to check for all columns in your CSV if they exist already. If not: add a new colum for it. If yes, leave it as is...
I'm writing sql code which gets the name of the columns its supposed to look up of a table from custom php code.
Part of this has to do with location i.e. country ,state, zip, etc. I have it so that on the php code, the user fills out the fields that correspond to these on their tables. However, it is possible that while these are all possibilities they may not have every piece, like the zip code.
If I the php doesn't get anything for the zip column name it throws off the entire code. Null columns are ok with me, but I'm struggling finding a way to make a placeholder for the column. Is there a sql placeholder I can tell the php variable to become if the user enters nothing and is therefore null?
$addressColumn = $_POST["address"];
$stateColumn = $_POST["state"];
$zipColumn = $_POST["zip"];
$cityColumn = $_POST["city"];
$countryColumn = $_POST["country"];
$database = $_POST["database"];
if one of these is not posted on the html page, then the code breaks. suggestions? I can change the value if null to something else if anyone knows of a placeholder value that sql will accept and then as I fetch rows will place null below it
I think that working starting from column names is not a good idea. SQL doesn't concept like stree or ZIP but only stings and number or date.
I suggest you to create a class with all your table columns as properties, putting the business logic in the right place (the PHP), so the method "query" (the one who query the DB) can validate/operate/manage the status of your object.
The PHP that draw the for can get all infos from the class (eg: *get_object_vars* ) instead of DB.
If you're worried from mapping your DB into class you can look at ActiveRecords.
I have a tab delimited text file with the first row being label headings that are also tab delimited, for example:
Name ID Money
Tom 239482 $2093984
Barry 293984 $92938
The only problem is that there are 30 some columns instead of 3 so I'd rather not have to type out all the (name VARCHAR(50),...) if it's avoidable.
How would I go about writing a function that creates the table from scratch in php from the text file, and say the function takes in $file_path and $table_name? Do I have to write all the column names again telling mysql what type they are and chop off the top or is there a more elegant solution when the names are already there?
You would somehow need to map the column type to the columns in your file. You could do this by adding that data to your textfile. For instance
Name|varchar(32) ID|int(8) Money|int(10)
Tom 239482 $2093984
Barry 293984 $92938
or something similar. Then write a function thet get's the column name and columntype using the first line and the data to fill the table with using all the other rows. You might also want to add a way to name the given table etc. However, this would probably be as much work (if not more) than creating SQL queries using you text file. Add a create table statement at the top and insert statements for each line. With search and replace this could be done very fast.
Even if you could find a way to do this, how would you determine the column type? I guess there would be some way to determine the type of the columns through checking for certain attributes (int, string, etc). And then you'd need to handle weird columns like Money, which might be seen as a string because of the dollar sign, but should almost certainly be stored as an integer.
Unless you plan on using this function quite a bit, I wouldn't bother spending time cobbling it together. Just fat finger the table creation. (Ctrl-C, Ctrl-V is your friend)
Given a result set, how can I determin the actual names of the fields specified in the query (NOT their aliases).
$query = "SELECT first AS First_Name, last AS Last_Name FROM people";
$dbResult = mysql_query($query);
$fieldCount = mysql_num_fields($dbResult);
for ($i=0; $i<$fieldCount; $i++) {
// Set some values
$fieldName = mysql_field_name($dbResult, $i);
}
This example returns field names, but in this example it returns the alias "First_Name" instead of the actual field name "first".
Is it possible to get the actual field name from such a query. Particularly if I am writing a function and have no idea what query will be thrown at it.
If you are using MySQLi:
http://www.php.net/manual/en/mysqli-result.fetch-field.php
The field object has a "orgname" property.
The "classic" MySQL equivalent function doesn't report back the original column names.
Short answer: you don't.
Long answer: Once the dataset is pulled by MySQL and sent back to PHP, the only information PHP now has is the columns, or aliases if you used them. There is no way to look at a result set and determine what the original column names were. You have to switch to another DB driver like mysqli to obtain this info.
Your question doesn't make sense.
What are you going to do if you get a derived column i.e.
select column_a + column_b as order_total from orders;
are you saying you want to know that the original query was column_a + column b ??
if so, you probably need to write a query parser, or get one off the internet.
I think the implementation of that is beyond the scope of your question though :)
I'm not 100% sure about this, but I would say: there is no way.
The MySQL gives you back the result set, nothing more. It does not return the select statement nor any details about it.
So you cannot get the original field names because the server will provide you the information you asked: alias names.
If you don't mind making a second query (and your using MySQL 5 or greater) you can ask information_schema for the names.
Check out MySQL Reference for the details:
SHOW COLUMNS FROM tbl_name;
if you have access to the string of the query you could try a regular expression to parse it.
I'm no regex master but you could chop up the string by looking at the text between 'select' and 'from' then grabbing all the field names as either
field FieldAlias
or
field as FieldAlias
If you're trying to write some functionality to let you know what fields are being fetched for handling updates - the only way to do this correctly is for it to present an SQL-less interface to the code above and manage all SQL generation itself. This is called a data abstraction layer.