Assuming I have this table:
What I want to do is change all column names that starts with letter C to another letter or another word.
I'm not very good in SQL, I have ability to do this using program languages like Java or any other.
But my purpose is using only SQL.
Is it possible?
You need to drop and recreate the table.
So:
1)Create a temp table with all the data and structure of the original table. This allows you to drop the original, then recreate it using the same name.
Create Table temp as select * from [Table_Name]
2)Drop the original table.
Drop table [Table_Name]
3)Create the new table, with the new column names.
Create Table Table_Name
(Name varchar(20),
Age int,
[New_C1] int,
[New_C2] int),
[New_C3] int),
)
4)Insert the data from the temp table into the new table:
Insert into Table_Name (Name, Age, New_C1, New_C2, New_C3)
Select (Name, Age, C1, C2, C3) FROM temp
5)Drop the temp table:
Drop table temp
Note
I highly recommend wrapping this in a transaction, that way you can rollback.
Related
In my SQL Server table, I have a table whose PK is GUID with lots of records already.
Now I want to add records which only needs to change the COMMON_ID and COMMON_ASSET_TYPE column of some existing records.
select * from My_Table where COMMON_ASSET_TYPE = "ASSET"
I am writing sql to copy above query result, changing COMMON_ID value to new GUID value and COMMON_ASSET_TYPE value from "ASSET" to "USER", then insert the new result into My_Table.
I do not know how to write it since now I feel it is a trouble to insert records manually.
Update:
I have far more columns in table and most of them are not nullable, I want to keep all these columns' data for new records except above two columns.Is there any way if I do not have to write all these column names in sql?
Try to use NEWID if you want to create new guid:
INSERT INTO dbo.YourTable
(
COMMON_ID,
COMMON_ASSET_TYPE
)
select NEWID(), 'User' as Common_Asset_Type
from My_Table
where COMMON_ASSET_TYPE = "ASSET"
UPDATE:
As a good practice I would suggest to write all column names explicitly to have a clean and clear insert statement. However, you can use the following construction, but it is not advisable in my opinion:
insert into table_One
select
id
, isnull(name,'Jon')
from table_Two
INSERT INTO My_Table (COMMON_ID,COMMON_LIMIT_IDENTITY, COMMON_CLASS_ID,COMMON_ASSET_TYPE)
SELECT NEWID(), COMMON_LIMIT_IDENTITY, COMMON_CLASS_ID,'USER'
FROM My_Table
WHERE COMMON_ASSET_TYPE = 'ASSET'
If I've understood correctly you want to take existing records in your table, modify them, and insert them as new records in the same table.
I'll assume ID column contains the the GUID?
I'd first create a temporary table
CREATE TABLE #myTempTable(
ID UNIQUEIDENTIFIER,
Name varchar(max),
... etc
);
Fill this temp table with the records to change with your SELECT statement.
Change the records in the temp table using UPDATE statement.
Finally, Insert those "new" records back into the primary table. with INSERT INTO SELECT statement.
You will probably have to sandwitch the INSERT INTO SELECT with IDENTITY_INSERT (on/off):
SET IDENTITY_INSERT schema_name.table_name ON
SET IDENTITY_INSERT schema_name.table_name OFF
IDENTITY_INSERT "Allows explicit values to be inserted into the identity column of a table."
I'm creating a C# Winforms application for recipe management in an industrial environment.
I created a SQL Server table with 130 columns. The table contains a column called CheckData (of datatype Timestamp), which I use to detect changes made to a row.
If I insert a new row to that table all works fine. The code I use is:
INSERT INTO tablename (Column1, column2, column3, column4)
VALUES (value1, value2, value3, value4)
I just assign values to major columns, the others get their default value. I do not assign a value to the timestamp field since it's written by the system.
Additionally, I want to copy a row from this table to the same table (duplicate a data record).
I copy the source row to a temporary table, drop the ID (primary key) and the timestamp fields in that temporary table and try to insert that only row in the temporary table into the table. This fails.
Here's the code:
SELECT *
INTO #temptable
FROM tablename
WHERE Recipe_No = 8;
ALTER TABLE #temptable DROP COLUMN ID, CHECKDATA;
ALTER TABLE #temptable REBUILD;
UPDATE #temptable
SET Recipe_No = 9, Recipe_Name = 'Test'
WHERE Recipe_No = 8;
INSERT INTO tablename
SELECT * FROM #temptable;
I don't understand where the difference is between inserting a new row thru INSERT INTO xxx (yyy) VALUES (zzz) and INSERT INTO xxx SELECT * FROM yyy. In both cases I don't try to write the timestamp value in the new row.
Does anybody have an idea what I'm missing here?
I don't understand where the difference is between inserting a new row thru INSERT INTO xxx (yyy) VALUES (zzz) and INSERT INTO xxx SELECT * FROM yyy.
With this,
INSERT INTO xxx SELECT * FROM yyy.
you are failing to specify the column mappings from the SELECT to the target table. You should always use
INSERT INTO xxx (Column1, Column2, . . .)
SELECT (Column1, Column2, . . .)
FROM yyy
Here's a simplified example of what you're attempting:
drop table if exists t
create table t(id int, a int)
insert into t(id,a) values (1,1)
select * into #t from t where id = 1
alter table #t drop column id
insert into t select * from #t
and it will fail with
Msg 213, Level 16, State 1, Line 12
Column name or number of supplied values does not match table definition.
because the temp table doesn't even have the same number of columns. And even if it did, you wouldn't know for sure that the column mappings were correct.
It is failing because essentially your command
INSERT INTO tablename SELECT * FROM #temptable;";
Is telling SQL - "Insert everything into this table from this temp table."
While you can work around this, I would say why don't you just try inserting into only the columns made available in your current table with only the values you would like to include. Instead of needing to drop the columns/values, you just don't import it to begin with.
An alternative - if you can write to a helper table, it may be beneficial to INSERT INTO that helper table, as opposed to a temp table, the values you have. Then transform that helper table, and THEN you can do INSERT INTO final_table SELECT * FROM helper. This should give you the results you're looking for.
I hope this is helpful, and I hope it explains why your current command is failing.
I have created a backup for my country table.
create table country_bkp as select * from country;
What SQL should I use to restore the country table to it's original state?
I can do
insert into country select * from country_bkp;
but it will just have duplicate entries and probably fail as primary key would be same .
Is there an SQL command to merge data back?
Last alternative would be
DROP TABLE country;
create table country as select * from country_bkp;
but I want to avoid this as all the grants/permissions would get lost by this.
Other cleaner way would be
delete from country ;
insert into country select * from country_bkp;
But I am looking for more of a merge approach without having to clear data from original table.
Instead of dropping the table, which, as you noted, would lose all the permission defitions, you could truncate it to just remove all the data, and then insert-select the old data:
TRUNCATE TABLE country;
INSERT INTO country SELECT * FROM county_bkp;
In my case, INSERT INTO country SELECT * FROM county_bkp; didnt work because:
It wouldnt let me insert in Primary Key column due to
indentity_insert being off by default.
My table had TimeStamp columns.
In that case:
allow identity_insert in the OriginalTable
insert query in which you mention all the columns of OriginalTable (Excluding TimeStamp Columns) and in Values select all columns from BackupTable (Excluding TimeStamp Columns)
restrict identity_insert in the OriginalTable at the end.
EXAMPLE:
Set Identity_insert OriginalTable ON
insert into OriginalTable (a,b,c,d,e, ....) --[Exclude TimeStamp Columns here]
Select a,b,c,d,e, .... from BackupTable --[Exclude TimeStamp Columns here]
Set Identity_insert OriginalTable Off
Only One Solution to Recover Data from Backup table is Rename Original table with random name and than rename Backup table with Original Table name in case if Identity Insert is ON for Original Table.
for example
Original Table - Invoice
Back Up Table - Invoice_back
Now Rename these tables :
Original Table - Invoice_xxx
Back Up Table - Invoice
I wish to make a new table with some data from the old, but also with new empty columns I can edit.
I would start with:
CREATE TABLE new_table AS SELECT ID, title, summary FROM old_table;
and then alter the table with new columns:
ALTER TABLE new_table ADD note datatype;
But I need my new empty column to be between title & summary, and not 'in the end' as ALTER gives me.
I would like to combine CREATE TABLE and CREATE TABLE AS SELECT - but is that possible?
What about:
CREATE TABLE new_table AS SELECT ID, title, '' AS note, summary FROM old_table;
If you wanted to have a specific datatype, you could try CAST. For example, CAST(1 as INTEGER) AS note
I'm currently trying to localize a database, and my strategy involves taking all localizable strings out of my various tables, and putting them into another table containing a StringID, a CultureID and the LocalizedString, which is then referenced within the original table by the StringID. The problem is that I need to change the datatype of the column containing the string from a varchar to an int and replace the string with its reference to the LocalizedStrings table.
I've already taken all my strings from the table and created entries in the LocalizedStrings table at this point using an INSERT INTO query. And my current efforts to solve my problem look like this:
SELECT column1, column2, ...
INTO TempTable
FROM OriginalTable
INNER JOIN LocalizedStrings
ON OriginalTable.StringColumn = LocalizedStrings.LocalizedString
ALTER TABLE OriginalTable
DROP COLUMN StringColumn
ALTER TABLE OriginalTable
ADD NameStringID int
INSERT INTO OriginalTable (NameStringID)
SELECT StringID FROM TempTable
DROP TABLE TempTable
However due to various nightmarish dependencies, I'm getting all kinds of exceptions trying to do this.
My question is, is there an easier way? I'd also considered just adding the new column and leaving the old one as a temporary workaround, but that's pretty messy.
ALTER TABLE OriginalTable
ADD NameStringID int
update OT
set NameStringID = LS.NameStringID
from OriginalTable OT
join LocalizedStrings LS on ls.StringColumn = OT.LocalizedString
You will need to repeat this process for every child table if they also used the StringColumn.
You will also need to adjust all stored procedures, queries, ORM mappings to use the new colulm.
Then when all have been changed, run
ALTER TABLE OriginalTable
DROP COLUMN StringColumn
And of course dropp the column onthe child tables too if need be.
If you know that all of your column contains integer values, what you can do is cast the column to integer, and create another one on the fly. Not sure if I am understand you correctly, but something similar to the following:
declare #test table(id varchar(50),name varchar(50))
insert into #test
select '1','Test 1'
insert into #test
select '2','Test 2'
select *, cast(id as int) as ConvertedToInt into #Result from #test
select * from #Result
drop table #Result