SQL Server - altering column default value - sql-server-2008

I need to alter a default value for a column in an existing table.
I assumed (and I actually found a few examples on the net "confirming" this) that I could do
ALTER TABLE table ALTER COLUMN column SET DEFAULT 'something' but I get syntax error and according to this http://msdn.microsoft.com/en-us/library/ms190273.aspx DEFAULT is not supported.
Next idea was to drop the default constraint from the database but I found that when the table was created the constraint was not named and SQL generates a random name with every deployment so I can't reference it by name.
I came up with a query from sys tables that returns the name of the constraint:
select o.name from sys.objects o
join sys.columns c on o.object_id = c.default_object_id
join sys.tables t on c.object_id = t.object_id
where t.name='TableName' and c.name='ColumnWithDefValue'
I'm about to write a query by string concatenation and I can't stop thinking about how there must be a better way to do all this. Any suggestions?
TL;DR version: what's the easiest way to alter a default constraint for a column in SQL Server R2?
Thanks

Looks like you have to drop the constraint and then recreate it
http://bypsoft.blogspot.com/2007/10/changing-default-column-values-sql.html

Related

Syntax error while creating table as a join of two tables

I'm trying to create new table by joining two tables, using the following query on a MySQL DBMS:
create table t11 as
SELECT * FROM banking
JOIN details ON details.[account number]= banking.[account number]
which is firing a syntax error. Where is the mistake in it?
Delimiting field and table names with brackets is SQL-Server notation. In MySQL you may want to use backticks instead.
CREATE TABLE t11 AS
SELECT *
FROM banking
JOIN details ON details.`account number` = banking.`account number`
Or avoid using them completely, if:
they're composed by one word
there's no correspondence with any MySQL reserved keyword.

Table missing... or not (MYSQL)?

Suddenly I've a strange problem with Mysql:
In the navigator I see the "company" table (even after refresh), but if I do SELECT * FROM company; says that the table does not exist.
With the command SHOW TABLES FROM smartex_develop; the table "company" is present, but if I use the command SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'smartex_develop'; the table is missing. It's very strange also considering that there are a lot of table with a foreign key of that table.
Someone know how to resolve it?
[SELECT * FROM company] 1
[SHOW TABLES FROM smartex_develop] 2
[SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'smartex_develop'] 3
We had a similar problem - a table suddenly went missing. In the logs we had:
Load table <name-of-missing-table> failed, the table has missing foreign key indexes. Turn off 'foreign_key_checks' and try again.
InnoDB: Foreign Key referenced table <name-of-missing-table> not found for foreign table <some-other-table>
This happened upon mysqld startup, so the root cause might have been much older than that. In our case, the root cause was charset conversions. We converted a few tables, and ended up with foreign keys where the column in one table and the column in the referenced table had different character sets.
How we solved:
Disable foreign key checks
Restart mysql -- the missing table will now reappear
Convert all the columns that reference each other to have the same character set. You can use this query: select table_name,column_name,CHARACTER_SET_NAME from INFORMATION_SCHEMA.COLUMNS where table_schema = 'myschema' and data_type='varchar';
Re-enable foreign key checks
Restart mysql -- all should be fine now

C API mysql Add columns if they don't exist incorrect syntax

I have searched everything I could ) Truly. But I can't find the correct way to add new columns only after checking if the column doesn't exist. I am writing a program in C.
Here is what I am doing, and I can't find my mistake in syntax. I will be very grateful for your help! I get an error You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use
//create buffer to store the query
char buff[1024];
//store query in the buffer
snprintf(buff, sizeof buff, "IF NOT EXISTS(SELECT * FROM information_schema.COLUMNS WHERE COLUMN_NAME = '%i' AND TABLE_NAME = '%s' AND TABLE_SCHEMA = '%s') THEN ALTER TABLE `%s`.`%s` ADD COLUMN `%i` INT; END IF;", value1, table, database, database, table, value1);
EDIT
I am editing the post to show what I am trying to achieve.
Using nested if statement in the main function, I have created the database and the table, and have populated the table with column names; my code is designed in a way that all functions are interrelated: only if connection is established, the program calls "create database" function; only if database is created, the program calls "create table" function; only if the table is created and initially only two columns are added (id and Names), the program calls the function to alter table in order to add other columns.
I do so because I need a for loop to loop those additional column names, which were created previously by my previous C program.
So the table should look like this:
id name 1988 1977 1966 1955
1 name1 value value value value
2 name2 value value value value
3 name3 value value value value
Each time the program is called, each function checks if database exists, then it is not created from scratch, if table exists, it is not created, and now I am stumbled on how to check of columns exist, because if they do, I get an error and the program can't move on.
To add a column you can do it like this
snprintf(
buff,
sizeof buff,
"ALTER TABLE `%s`.`%s` ADD COLUMN IF NOT EXISTS `%s` `%s`",
database,
table,
column_name,
column_type
);
Note that in your format string there is a %i that doesn't look right.
After giving you the answer, because this is what you asked for, I want to say that adding a column in code like that looks like a bad sign. SQL databases are pretty static in their structure, you should never need to add or remove columns from it. If you have to, then there is a problem either in the database design or the way you are handling it.
According to the comments below you need something like this
CREATE TABLE `names` (
`name` VARCHAR(128) PRIMARY KEY
) ENGINE = InnoDB;
CREATE TABLE `entries` (
`name` VARCHAR(128) NOT NULL,
`year` INTEGER NOT NULL,
-- Or the required type (FLOAT perhaps?)
`value` INTEGER NOT NULL,
-- All names MUST come from the `names` table
CONSTRAINT `name_fk` FOREIGN KEY (`name`) REFERENCES `names` (`name`),
-- Allow only one entry per `name`/`year`
CONSTRAINT `entry_pk` PRIMARY KEY (`name`, `year`)
) ENGINE = InnoDB;
And then you can insert each name in the names table, and one entry per year in the entries table, you can have the combinations you want and you can query all years for a given name
SELECT * FROM `entries` WHERE `name` = ?
Creating a database schema dynamically is wrong, it's just against the whole idea of a schema, a database has a schema so you can write queries an rely on them working, the language is called Structured Query Language for a reason.

how to modify a column datatype in mysql so that it saves the previous records in the newly saved format

I just need to change the datatype of my column
however, I used the command
alter *table_name* modify column *column_name* *datatype* and it update the datatype but the previously saved result are in the same previous datatype . I want them to be modified too. Any help? And am I clear with my query?
It's been a while and I've been bouncing between database engines a lot lately so my syntax may be off, but the general idea will still be valid:
SELECT * INTO <table_name>_bak FROM <table_name>;
-- alter your table, leaving nulls in the column
UPDATE <table_name>
SET <column_name> = b.<column_name>
FROM <table_name> t
INNER JOIN <table_name>_bak ON <primary-key-join-clause-here>;
-- disable nulls in your modified column if needed
DROP TABLE <table_name>_bak;

Creating Unique Compound Index where one field can be null in Mysql

I created Unique Compound Index:
Alter Table TableX Add Unique Index `UniqueRecord` (A,B,C,D)
The issue is that sometimes C can be NULL.
I noticed that
`Insert IGNORE`
Was still in some cases adding duplicate records and this turned out to be when those incoming records had C as NULL.
I tested the hypothesis that this was an issue by doing:
Select concat(A,B,C,D) as Index from TableA where C is NULL
And Index in each of those cases was in fact NULL. Once I remove the null field from the select:
Select concat(A,B,D) as Index from TableA where C is NULL
I get the expected string values vs nulls.
So the question is, other than doing an update like set C='' where C is NULL is there some way to set up the Index so that it works? I am loathe to simply make the Index A,B,D as that might introduce unwanted dupes when C in fact is not NULL.
Update:
I did try using IfNull in the Index creation but Mysql did not like that:
Alter Table TableA Add Unique Index UniqueLocator (A,B,IfNull(C,''),D
Mysql said:
[Err] 1064 - You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version
for the right syntax to use near 'C,''),D)' at line 1
Yes MySQL allows NULLs in unique indexes, which is the right thing to do. But you can define column C as NOT NULL if you don't like that.
MySQL -- but not all databases -- allow duplicate NULL values in unique indexes. I believe the ANSI standard is rather ambiguous on this point (or perhaps even contradictory). You basically have two choices.
The first is to define a default value for the column. This may not be appealing in terms of code, but it will at least generate an error on duplicate insert. For instance, if "C" is a foreign key reference to an auto-incremented id, then you might use -1 or 0 as the default value. If it is a date, you might use the zero date.
The other solution is a trigger, where you manually check for the duplicate values before doing an insert (or update).