views:

567

answers:

6

I need to copy a table I already I have in a SQL server database, but I don't need th edata contained in the source table. The examples I found only involve copying the data.

  1. Copy the table structure only, not the data.
  2. Source and target tables are in the same database.
  3. Target table does not exist yet.
  4. Need to do this programmatically
  5. It would be nice to have any related properties of the table/columns be copied as well.

Thanks!

+3  A: 

Script out the table, change the table name in the script, run the script.

MusiGenesis
Sorry I should I put in my question that I want to programmatically do this.
SkippyFire
+1  A: 

In SQL Management Studio, right click on the table name and Script Table as | CREATE TO ... | New Query editor Window. That will give you a script that you can run under any database.

Jeff Hornby
Any database except the original DB, which is what the asker needs.
MusiGenesis
A: 

Do you need to do this automatically (without manual interference)?

Otherwise, you can always use SQL Server Management Studio to generate CREATE scripts for the tables you want to copy and run it on the target database.

Right click on the object you want, pick generate script, and choose your script to generate.

Adrian Godong
Needs to be automatic.
SkippyFire
+5  A: 

select * into new_table from old_table where 1=0

Execute the above command programmatically.

msvcyc
what I was thinking, but it will not do anything "extra", index, constraints, defaults, pk, fk. It will do identities, though...
KM
Nice, but that won't copy primary/foreign keys, identity columns, constraints, etc. (OP might not need those things, though.)
Ben M
@Ben M, it will do identities
KM
+2  A: 

I bet with SMO you can do this no problem:

  • read the structure of your "old" table into in-memory variables
  • use this structure info to create the new table

I quickly found a few interesting articles that show at least part of the solution:

So basically it would boil down to something like this:

Server localServer = new Server("(local)");
Database testDB = localServer.Databases["test"];

Table myTable = testDB.Tables["TestFiles"];
myTable.Refresh();

Table newTable = new Table(testDB, "MyNewTableName");

foreach(Column col in myTable.Columns)
{
    Column newColumn = new Column(newTable, col.Name);

    newColumn.DataType = col.DataType;
    newColumn.Default = col.Default;
    newColumn.Identity = col.Identity;
    newColumn.IdentityIncrement = col.IdentityIncrement;
    newColumn.IdentitySeed = col.IdentitySeed;
    newColumn.Nullable = col.Nullable;

    newTable.Columns.Add(newColumn);
}

newTable.Create();

Of course, there are more properties on the "Column" which you might want to copy over, plus you might also want to copy indices, constraints etc. - extra work.

I'm stumped that there isn't an easier way to duplicate a "Column" object to a new one (something like a .Clone() method) to ease this - maybe it's not a top-priority scenario, I don't know....

Hope this helps!

Marc

marc_s
We could always add a clone extension method :)
SkippyFire
@SkippyFire: sure - I was just stumped that it's not in there already.
marc_s
+1  A: 

If you're using .NET, you can use Server Management Objects:

var so = new ScriptingOptions();
so.Triggers = true;
so.DriForeignKeys = true;
so.DriDefaults = true;
so.DriAllConstraints = true;
so.DriAllKeys = true;
so.DriIndexes = true;
so.DriUniqueKeys = true;
so.DriPrimaryKey = true;
so.Indexes = true;
so.Default = true;
so.ClusteredIndexes = true;
so.IncludeDatabaseContext = true;
so.TargetServerVersion = SqlServerVersion.Version90;

var server = new Server("ServerName");
var db = server.Databases["DatabaseName"];
var stringColl = db.Tables["Table"].Script(so);

You'd need to replace the names of the table and associated objects (e.g. FK_OldTableName_xxx with FK_NewTableName_xxx) in the generated script:

var sb = new StringBuilder();
foreach(var s in stringColl)
{
    var r = s.Replace("OldTableName", "NewTableName");
    sb.AppendLine(r);
}

And then execute:

db.Execute(sb.ToString());

Note that this is pretty naive code: it will only work if the names of your constraints and keys follow the format: FK_OldTableName_xxx / CK_OldTableName_xxx .. if they have other names, you'd need to beef up the string replacement code, probably using Regexes to look for T-SQL object creation patterns (i.e. CREATE INDEX, FOREIGN KEY .. etc).

Ben M
marc_s's is another approach using SMO, and although more work to implement is probably less error-prone than mine if you want to perform this task in a wide variety of situations.
Ben M
Yes, that sounds about right, but thank you for this information Ben! This could definitely come in handy for other purpose, like auto generating backup scripts and things like that.
SkippyFire