views:

23

answers:

2

I know my title isn't exactly worded well, so let me clarify. I'm using SQL Server 2005 Express.

I have a table that basically stores a "template," if you will. Using a car as an example, the fields would be something like:

TemplateID
Color
Make
Model

Now, I have another table that represents an "instance" of the template. It contains all the fields of the template table plus some fields that are unique to an instance:

InstanceID
VIN
SerialNumber
Color
Make
Model

I am writing a stored procedure to insert a new row into the "Instance" table. This stored procedure will take input parameters for "VIN" and "SerialNumber," but I want it to copy "Color", "Make", and "Model" from the appropriate "Template." The template is located by the "TemplateID," which is already known.

I am looking for advice on how to write this stored procedure. It would be simple if it weren't for the fact that these tables contain 100+ fields (I didn't design them but I'm stuck using them.) I would like to do something like:

INSERT INTO Instance(VIN, SerialNumber, "EverythingElse") 
VALUES (@VIN, @SerialNumber, SELECT * FROM Template WHERE TemplateID = 1)

In other words, I only want to supply (through parameters) those fields not stored in the "Template" and copy everything else from the template. Is anything like this possible without hand coding for every field?

A: 

Just do a INSERT INTO and use a SELECT statement instead of a values statement.

INSERT INTO Instance(VIN, SerialNumber, a, b, c) 
SELECT @VIN, @SerialNumber, a, b, c FROM Template WHERE TemplateID = 1;

You really don't want to use *. You can have SQL Server Managemnt Studio script a SELECT statement for you and it will generate the field names so you don't have to type them.

ctrlShiftBryan
The only problem with this is that I would have 100+ field names (a,b,c,.......). I'm trying to avoid creating a super long query like that. I realize that it may not be possible, but thought I would ask to see if there was a better way.
Casey
See my other answer.
ctrlShiftBryan
WHy would you object to 100 column names? If that's waht itis, that's what itisi. Personally I drag and drop them from the object oexporer when writing d=code, but that's just me. This is abetter solution that the dynamic one above.
HLGEM
Agreed it is possible but the best way is to actually have all the field names typed out.
ctrlShiftBryan
Not so much that I absolutely object to it, as I like to write concise code. If I can do the same thing with 2 lines instead of 20, I like to do so. I fully realize that there may not be a "shorthand" in this case.
Casey
+1  A: 

Then you can use dynamic SQL like this...

DECLARE
    @Fields nvarchar(Max),
    @SQL nvarchar(Max);

SELECT
    @Fields = COALESCE(@Fields + ',', '') + column_name
FROM
    information_schema.columns
WHERE
    table_schema = 'dbo' AND
    table_name = 'Instance' AND
    column_name <> 'PrimaryKeyID' --here you exclude columns
ORDER BY
    ordinal_position;


SET @SQL = 'INSERT INTO dbo.Instance' 
    + ' ('
    + @Fields
    + ') SELECT '
    + ' ('
    + @Fields
    + ') FROM Template;'            

EXECUTE sp_executesql @SQL;
ctrlShiftBryan