views:

255

answers:

7

I want to duplicate a row, not the keys of course, without explicity using the field names.
Is there a SQL way or do I have to enumerate the field names through code?

I don't want to explicity use field names because I want to minimize code and db dependencies.

I am going to use it in the Ms Access 2003. I mention it in case that no standard way exists.

+3  A: 

If you don't have any uniques to worry about:

INSERT INTO <table> (SELECT * FROM <table> WHERE <condition>)

Otherwise, John Saunders' answer is probably your best bet.

Noah Medling
-1: Won't work if primary key or unique constraints exist.
John Saunders
He asked for a duplicate row without mentioning any field names; working around unique constraints prevents you from getting an exact duplicate and requires that you mention each the field names you intend to copy.
Noah Medling
Then surely the correct answer, @Noah, is "no, you can't do it".
paxdiablo
it doesn't work. Access alerts me with a INSERT INTO syntax error. Yes, I do use primary keys but I don't know if the primary key is the reason for that error.
Nick D
@Nick: You replaced <table> and <condition> with the appropriate table and condition, right? Also, primary keys count as uniques and will prevent my answer from working.
Noah Medling
Add a trigger 'before insert' and auto-increment your PK, and you just have built the best gas factory ever made.Else you can do what John advise !
Scorpi0
of course, Noah.
Nick D
A: 

If your primary key fields have automatic identifiers then you might well be able to script to interogate the system for fields which are not in the PK, and use the existing values for those that are not and only insert those ones (or to insert null for the PK fields).

Consequently I don't think there is going to be a "standard" way.

Unsliced
+5  A: 
INSERT INTO `<table>` (column1, column2, ...) -- Not IDENTITY columns
SELECT column1, column2, ... FROM ...

This will also allow you to insert replacement values for the primary key columns, etc. I've used this, along with a common table expression, to take a set of test data from the month of February, and to pretend they're really from June.

I know you said you want to do it without the field names, but I don't think you can. It's also not a good idea, as it would tie you to the order of the columns.

John Saunders
Yeah, stop yer whinin' up and write some code :-) +1.
paxdiablo
John, that sort of code I would like to avoid. Perhaps I'll auto generate it with VBA code.
Nick D
@Nick D. You'll have to. There's no generic way to say: insert all the columns, except for the ones I don't want.
John Saunders
Thank you John. I'll generate that SQL command with VBA.
Nick D
A: 

I'm not an Access person, but in SQL Server you can choose "Script table as --> Insert into" in SQL Server Management Studio. You can easily modify this to filter the rows you want into an INSERT INTO SELECT statement.

Perhaps something like this exists in Access?

RichardOD
I am not an Access person either :) ok, I'll check it out.
Nick D
No such facility exists in Access. Or Jet/ACE, for that matter.
David-W-Fenton
That's a shame, I guess you could import the table into SQL Server then create the script and run it in Access, but that is probably more effort than it is worth, and assumes the user has SQL Server.
RichardOD
A: 

Like folks have stated before me, you can do "INSERT INTO TBL SELECT * FROM TBL WHERE X=Y" and you will get one row. And this will fail if you have a primary key.

If you do not have a PK then you probably have bigger problems.

Is this a linked table? If so, there are no database dependencies, because you are dealing with an ODBC link. In that case, you can easily use this to get a list of columns for the table:

SELECT TOP 0 * FROM TBL (on linked tbl will need a round trip to server)
You get a blank recordset, and you just iterate through the columns.

Raj More
1,1s/primary key/unique constraint/ - a primary key is only one type of unique constraint.
paxdiablo
A: 

Ms Access 2003 oriented solution

I have a form where the user can press a button to create a new version of the current record.
That part in Ms Access is easy:

DoCmd.GoToRecord , , acNewRec

Now I need to update all the fields on the form (controls are bind with table fields) except the key, ie "id" field, with data from some other record.

I came up with the below routine, which worked good for me:

Private Sub UpdateRow(tblname As String, key_name As String, key_value As String)
    Dim Rst As Recordset
    Dim field As field

    Set DB = CurrentDb
    Set Rst = DB.OpenRecordset("select * from " & tblname & " where " & _
      key_name & "=" & key_value, dbOpenDynaset)

    For Each field In Rst.Fields
       If field.Name <> key_name Then
           Form(field.Name) = field
       End If
    Next field

    Rst.Close
    Set Rst = Nothing
    Set DB = Nothing
End Sub


And I use it like this:

DoCmd.GoToRecord , , acNewRec
UpdateRow "TableName", "KeyName", "some_previous_key_value"
Form.Refresh
Nick D
A: 

You would need to explicitly supply the field names for the keys when you supply replacement values, therefore a 'standard' way is simply not possible.

...unless all you tables have a single key, all with the same name (ID is popular), and each key consists of a single column that has the IDENTITY (autonumber) property, in which case you would in fact have no keys at all, merely a way of using the IDENTITY value to uniquely identify your duplicate rows!

onedaywhen