I'm trying to design some tables and wondering if I'm missing the correct way to do it. For example, I have a 'main' table (would hold any top level generic info) and I have a field in that table 'type'. Right now I have a different table for each 'type' so I'm using if statements to grab the correct info.
So select * from Main -> then using that type field value to determine which table I need to get my more detailed information from. If type is 1 query TableA... if type is 2 query TableB... etc...
Right now this is working... there is a fixed amount of 'types' but I'm pretty helpless on any nice JOIN statements in this scenario.
Does this make sense? Just seems like I'm doing this a really messed up way.... Thanks for any help or suggestions.
Depending on the language you re using, you could generate your SQL dynamically, placing the 'type' table into the dynamic SQL and doing JOINs that way. We do something like this in an application that uses C++, C#, PHP and SQL Server stored procedures, and dynamic SQL is our solution.
Related
After selecting data from multiple tables, like this:
SELECT games.name, scores.score
FROM games, scores
WHERE players.id = scores.player_id
..can I extract the column headings of this newly generated table?
The statement I'd normally use would be as follows:
SELECT column_name
FROM information_schema.columns
WHERE table_name=table
But naturally this would not work for a dynamically generated table with no name
Help much appreciated!
Edit: I'm using the MariaDB client
..can I extract the column headings of this newly generated table?
No. Mostly because you've not created a table. Just a result set. I think you already know this, because you've already looked at the information schema :)
Unfortunately it seems even creating a temporary table won't help - because those aren't stored in the information schema either. I don't think you can declare cursors for SHOW COLUMN... statements either.
I don't think you've got a way to do it I'm afraid.
If it's a prepared statement (with the select statement held in a variable) you could probably chop it up using some ugly string manipulation...?
It might at this point be worth asking "more abstractly, what problem are you trying to solve?"
I'm building a MySQL event to make a copy of a table in the database with a timestamp in the name.
CREATE TABLE `db_name`.`tbl_prefix_(SELECT TO_SECONDS(NOW()))` ( [the rest...]
Obviously this isn't working. What should I do to make it work?
Any suggestions are welcome.
Thanks
This is a bad architecture. Generating tables on the fly is not something you should do.
Instead, create a single table with a timestamp column. For instance, if you would before have 3 tables with three timestamps A, B, and C, you now have one table with a timestamp column containing the values A, B, and C, respectively.
In order to do this, you would need to use "dynamic SQL". That is, make use of the MySQL PREPARE statement.
What you'd need to do is populate a variable with a string that contains the SQL text you want to execute. Doing variable substitution into string is trivial.
The "trick" is to take that dynamic string and execute it like it was a SQL statement.
And that's what the PREPARE statement does for us, takes in a variable, and reads the contents of that variable like it were a SQL statement.
With that said, rather than give an example code that demonstrates this in more detail, I'm going to suggest that you re-think this idea of creating a table with timestamp value as part of the name.
What problem is that designed to solve? And carefully consider whether the proposed design for a solution will introduce a bigger problem than it solves.
I know this is a very poor database design,but still i want to know is there any way to search a keyword in all the columns in that table through Mysql query(not Php)?
I've searched in internet but didn't find any help regarding this? if nothing such possibilty is there,then i think dividing the table is only the option left
You cannot use wildcards and anything like that on column names. Either select all columns with *or name the ones you need.
You could use dynamic SQL to patch your query together but this will probably only give you more problems handling it.
I'd like to select * from 2 tables, but have each table's column name be prefixed with a string, to avoid duplicate column name collissions.
For example, I'd like to have a view like so:
CREATE VIEW view_user_info as (
SELECT
u.*,
ux.*
FROM
user u,
user_ex ux
);
where the results all had each column prefixed with the name of the table:
e.g.
user_ID
user_EMAIL
user_ex_ID
user_ex_TITLE
user_ex_SIN
etc.
I've put a sql fiddle here that has the concept, but not the correct syntax of course (if it's even possible).
I'm using MySql, but would welcome generic solutions if they exist!
EDIT: I am aware that I could alias each of the fields, as mentioned in one of the comments. That's what I'm currently doing, but I find at the start of a project I keep having to sync up my tables and views as they change. I like the views to have everything in them from each table, and then I manually select out what I need. Kind of a lazy approach, but this would allow me to iterate quicker, and only optimize when it's needed.
I find at the start of a project I keep having to sync up my tables and views as they change.
Since the thing you're trying to do is not really supported by standard SQL, and you keep modifying database structures in development, I wonder if your best approach would be to write a little script that recreates that SELECT statement for you. Maybe wrap it in a method call in the development language of your choice?
Essentially you'd need to query INFORMATION_SCHEMA for the tables and columns of interest, probably via a join, and write the results out in SQL style.
Then just run the script every time you make database structural changes that are important to you, and watch your code magically keep up.
I have a table in the database with the following columns: ID, Name, Txt. We are using Linq To Sql to implement our DAL. In there another collegue added two extra columns so in the code the same table results: ID, Name, Txt, NameTemp, TxtTemp.
These two "fake" tables are used in different parts of the code in LINQ joins and analyzing with SQL Profiler the parsed SQL query takes the "real" columns and everything works properly.
Now I need to make an INSERT using that table, but I get an exception since also the fake columns are used in the statement.
Since I cannot add the two fake columns in the DB(since unuseful there), is there a way in which I could make an insert with Linq omitting these two columns?
I think i know where you're getting at. You should be able to add properties to a partial linq class no problem, only thing is that if you try and use a linq query against these "fake" columns, you'll get an exception when linqtosql tries to reference a column that doesn't exist in the database. I've been through this before - i wanted to be able to select columns that don't exist in the database (but do in the linq2sql dbml class) and have linq2sql translate the columns into what they really are in the database. Only problem is that there's no real easy way to do this - you can add attributes to the "fake" properties so that linq2sql thinks that NameTmp and TxtTmp are in fact Name and Txt in the sql world, only problem is that when it comes to inserting a record, the translated sql specifies the same column twice (which SQL doesn't like and throws an exception).
You can mark the column with IsDbGenerated = true - that'll let you insert records without getting the double column problem, but you can't update a record without linqtosql complaining that you can't update a computed column. I guess you can use a sproc to get around this perhaps?
I logged a bug with Microsoft a while back, which they'll never fix. The info here might help you get what you need -
http://social.msdn.microsoft.com/Forums/eu/linqtosql/thread/5691e0ad-ad67-47ea-ae2c-9432e4e4bd46
https://connect.microsoft.com/VisualStudio/feedback/details/526402/linq2sql-doesnt-like-it-when-you-wrap-column-properties-with-properties-in-an-interface
LINQ is not for inserting data, but for querying only - Language INtegrated Query. Use ADO.NET for inserting the data.
(Leaving the first part to remind my stupidity)
Check ScottGu. The classes generated are partial (mentioned here), so you can put your 2 properties into the editable part and since they won't have any mapping attribute defined, they won't be mapped nor persisted.