SQL 테이블에서 레코드를 어떻게 복사하지만 새 행의 고유 ID를 교체합니까?
이 질문 은 내가 필요한 것에 가깝지만 시나리오는 약간 다릅니다. 소스 테이블과 대상 테이블은 동일하며 기본 키는 고유 식별자 (guid)입니다. 내가 이것을 시도하면 :
insert into MyTable
select * from MyTable where uniqueId = @Id;
기본 키를 복사하려고 시도하기 때문에 기본 키 제약 조건 위반이 발생합니다. 사실, 기본 키를 전혀 복사하고 싶지 않습니다. 오히려 새로운 것을 만들고 싶습니다. 또한 특정 필드를 선택적으로 복사하고 다른 필드는 null로 남겨두고 싶습니다. 문제를 좀 더 복잡하게하려면 원본 레코드의 기본 키를 가져 와서 사본의 다른 필드 (PreviousId 필드)에 삽입해야합니다.
나는 이것에 대한 쉬운 해결책이 있다고 확신한다. 나는 그것이 무엇인지 알기에 충분한 TSQL을 모른다.
이 시도:
insert into MyTable(field1, field2, id_backup)
select field1, field2, uniqueId from MyTable where uniqueId = @Id;
지정되지 않은 모든 필드는 기본값을 받아야합니다 (정의되지 않은 경우 일반적으로 NULL 임).
좋아, 나는 그것이 오래된 문제라는 것을 알고 있지만 어쨌든 내 대답을 게시합니다.
나는이 해결책을 좋아한다. ID 열만 지정하면됩니다.
SELECT * INTO TempTable FROM MyTable_T WHERE id = 1;
ALTER TABLE TempTable DROP COLUMN id;
INSERT INTO MyTable_T SELECT * FROM TempTable;
DROP TABLE TempTable;
"id"-열은 ID 열이며 이것이 내가 지정해야하는 유일한 열입니다. 어쨌든 다른 방법보다 낫습니다. :-)
SQL Server를 사용합니다. 1 행과 2 행에서 " CREATE TABLE
"와 " UPDATE TABLE
" 를 사용하고 싶을 것입니다. 그는 ID를 다른 열에도 복사하려고했습니다. 그러나이 솔루션은 새로운 자동 ID로 사본을 만드는 데 좋습니다.
Michael Dibbets의 아이디어로 솔루션을 편집합니다.
use MyDatabase;
SELECT * INTO #TempTable FROM [MyTable] WHERE [IndexField] = :id;
ALTER TABLE #TempTable DROP COLUMN [IndexField];
INSERT INTO [MyTable] SELECT * FROM #TempTable;
DROP TABLE #TempTable;
","로 구분하여 둘 이상의 열을 삭제할 수 있습니다. : id는 복사하려는 행의 ID로 바꿔야합니다. MyDatabase, MyTable 및 IndexField는 물론 이름으로 바꿔야합니다.
모든 열 이름을 쓰지 않으려 고 생각합니다. SQL Management Studio를 사용하는 경우 테이블과 스크립트로 삽입을 쉽게 마우스 오른쪽 단추로 클릭 할 수 있습니다. 그러면 해당 출력을 엉망으로 만들 수 있습니다.
ID 필드를 제외한 모든 필드를 지정하십시오.
INSERT INTO MyTable (FIELD2, FIELD3, ..., FIELD529, PreviousId)
SELECT FIELD2, NULL, ..., FIELD529, FIELD1
FROM MyTable
WHERE FIELD1 = @Id;
다른 개발자가 정기적으로 열을 추가 한 테이블에서 단일 스크립트를 사용하려는 동일한 문제가 있습니다. 뿐만 아니라 고객이 현재 버전을 모두 최신 상태로 유지할 수 없기 때문에 다양한 데이터베이스 버전을 지원하고 있습니다.
Jonas가 솔루션을 가져 와서 약간 수정했습니다. 이를 통해 행의 사본을 작성한 다음 기본 소스 테이블에 다시 추가하기 전에 기본 키를 변경할 수 있습니다. 이것은 또한 열에 NULL 값을 허용하지 않는 테이블 작업에 유용하며 INSERT에서 각 열 이름을 지정하지 않아도됩니다.
이 코드는 'ABC'에 대한 행을 'XYZ'에 복사합니다.
SELECT * INTO #TempRow FROM SourceTable WHERE KeyColumn = 'ABC';
UPDATE #TempRow SET KeyColumn = 'XYZ';
INSERT INTO SourceTable SELECT * FROM #TempRow;
DELETE #TempRow;
임시 테이블을 삭제 한 후에.
DROP TABLE #TempRow;
insert into MyTable (uniqueId, column1, column2, referencedUniqueId)
select NewGuid(), // don't know this syntax, sorry
column1,
column2,
uniqueId,
from MyTable where uniqueId = @Id
내 답변이 파티에 늦다는 것을 알고 있습니다. 그러나 내가 해결 한 방법은 모든 답변과 약간 다릅니다.
상황이 있었는데 몇 열을 제외하고 테이블의 행을 복제해야합니다. 그 몇 사람은 새로운 가치를 가질 것입니다. 이 프로세스는 향후 테이블 변경을 자동으로 지원해야합니다. 이것은 열 이름을 지정하지 않고 레코드를 복제 함을 의미합니다.
나의 접근 방식은
- Query Sys.Columns to get the full list of columns for the table and include the names of columns to skip in where clause.
- Convert that in to CSV as column names.
- Build Select ... Insert into script based on this.
declare @columnsToCopyValues varchar(max), @query varchar(max)
SET @columnsToCopyValues = ''
--Get all the columns execpt Identity columns and Other columns to be excluded. Say IndentityColumn, Column1, Column2
Select @columnsToCopyValues = @columnsToCopyValues + [name] + ', ' from sys.columns c where c.object_id = OBJECT_ID('YourTableName') and name not in ('IndentityColumn','Column1','Column2')
Select @columnsToCopyValues = SUBSTRING(@columnsToCopyValues, 0, LEN(@columnsToCopyValues))
print @columnsToCopyValues
Select @query = CONCAT('insert into YourTableName (',@columnsToCopyValues,', Column1, Column2) select ', @columnsToCopyValues, ',''Value1'',''Value2'',', ' from YourTableName where IndentityColumn =''' , @searchVariable,'''')
print @query
exec (@query)
If "key" is your PK field and it's autonumeric.
insert into MyTable (field1, field2, field3, parentkey)
select field1, field2, null, key from MyTable where uniqueId = @Id
it will generate a new record, copying field1 and field2 from the original record
My table has 100 fields, and I needed a query to just work. Now I can switch out any number of fields with some basic conditional logic and not worry about its ordinal position.
Replace the below table name with your table name
SQLcolums = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE (TABLE_NAME = 'TABLE-NAME')" Set GetColumns = Conn.Execute(SQLcolums) Do WHILE not GetColumns.eof colName = GetColumns("COLUMN_NAME")
Replace the original identity field name with your PK field name
IF colName = "ORIGINAL-IDENTITY-FIELD-NAME" THEN ' ASSUMING THAT YOUR PRIMARY KEY IS THE FIRST FIELD DONT WORRY ABOUT COMMAS AND SPACES columnListSOURCE = colName columnListTARGET = "[PreviousId field name]" ELSE columnListSOURCE = columnListSOURCE & colName columnListTARGET = columnListTARGET & colName END IF GetColumns.movenext loop GetColumns.close
Replace the table names again (both target table name and source table name); edit your
where
conditionsSQL = "INSERT INTO TARGET-TABLE-NAME (" & columnListTARGET & ") SELECT " & columnListSOURCE & " FROM SOURCE-TABLE-NAME WHERE (FIELDNAME = FIELDVALUE)" Conn.Execute(SQL)
You can do like this:
INSERT INTO DENI/FRIEN01P
SELECT
RCRDID+112,
PROFESION,
NAME,
SURNAME,
AGE,
RCRDTYP,
RCRDLCU,
RCRDLCT,
RCRDLCD
FROM
FRIEN01P
There instead of 112 you should put a number of the maximum id in table DENI/FRIEN01P.
Here is how I did it using ASP classic and couldn't quite get it to work with the answers above and I wanted to be able to copy a product in our system to a new product_id and needed it to be able to work even when we add in more columns to the table.
Cn.Execute("CREATE TEMPORARY TABLE temprow AS SELECT * FROM product WHERE product_id = '12345'")
Cn.Execute("UPDATE temprow SET product_id = '34567'")
Cn.Execute("INSERT INTO product SELECT * FROM temprow")
Cn.Execute("DELETE temprow")
Cn.Execute("DROP TABLE temprow")
'Programing' 카테고리의 다른 글
'for'루프를 사용하여 C ++ 벡터를 반복 (0) | 2020.07.21 |
---|---|
방랑자 역 포트 포워딩? (0) | 2020.07.21 |
많은 수의 파일에 대한 빠른 Linux 파일 수 (0) | 2020.07.21 |
UNIX / LINUX에서 명령이 걸리는 시간을 추적 하시겠습니까? (0) | 2020.07.20 |
WebDriver click () vs JavaScript click () (0) | 2020.07.20 |