8

SQL データベース内

私はテーブルユーザーを持っています

 Id   Name   Age    AddressId
----+------+------+-----------

AddressId は、テーブル名 Addresses への外部キーです。

アドレス テーブル:

 Id   Country   State  City   ZipCode
----+---------+------+------+---------

これは 1 対 1 の関係です。各ユーザーには 1 つのアドレスがあり、各アドレスには 1 人のユーザーがいます。

NEWUsersという名前の新しいテーブルがあります

Id   Name  
----+------

Id と Name しかありません。

私がやりたいことはこれです:

NEWUSers テーブルのすべてのレコードを Users テーブルに挿入するスクリプトを作成します。

  • すべての新規ユーザーの年齢をデフォルトの 20 にしたい
  • そして、挿入された新しいユーザーごとに、彼のために新しい Address レコードを作成する必要があります
  • 新しい Address レコードには、新しいユーザーの外部キー AddressId を設定するために使用される Id を除いて、すべての値 (国、都市、州、郵便番号) が "abcd" に等しくなります)

どうやってやるの?

私は次のことを試しました:

INSERT INTO Users(Name, Age)
Values((SELECT Name FROM NewUsers),20)

しかし、挿入されたユーザーごとに新しい Address レコードを作成し、それに応じて外部キーを指定する方法がわかりません。

助けてくれてありがとう

4

5 に答える 5

6

1 つの方法は、次のように形成された 2 つのクエリを使用することです。

INSERT INTO Addresses (Country, State, City, ZipCode)
SELECT 'abcd', 'abcd', 'abcd', 'abcd' FROM NewUsers

INSERT INTO Users (Name, Age, AddressId)
SELECT Name, 20, ?? FROM NewUsers

編集:ユーザーをアドレスにリンクする簡単な方法の 1 つは、一時的に国をユーザー名に設定することです。次に、addressId を特定するためのリンクがあります。users テーブルにデータが入力され、適切にリンクされたら、country をデフォルト値に戻すことができますabcd

insert addresses (country, state, city, zipcode)
select name, 'abcd', 'abcd', 'abcd' from newusers;

insert users (name, age, addressid)
select u.name, 20, a.id from newusers u
join addresses a on a.country = u.name;

update a
set a.country = 'abcd'
from addresses a join newusers u on a.country = u.name;

デモ: http://www.sqlfiddle.com/#!3/1f09b/8

複数の挿入が同時に発生する可能性がある場合にトランザクションの一貫性を保証したい場合、または名前の重複を許可したい場合など、これを行うにはより複雑な方法があります。ただし、指定した例とこれまでの詳細に基づいて、この方法は仕事。

于 2012-05-24T16:20:43.950 に答える
2

ユーザーに挿入するためのカーソルとForignキーを使用したアドレステーブルを作成する必要があります

DECLARE @AddressID INT,
        @ID INT,
        @Name NVARCHAR(50)

DECLARE UserCursor CURSOR FOR
SELECT ID, NAME
FROM NewUsers
OPEN UserCursor

FETCH NEXT FROM UserCursor INTO @ID, @Name
WHILE @@FETCH_STATUS =0 BEGIN
    INSERT INTO Addresses(Country, State, City, ZipCode)
    VALUES ('abcd', 'abcd', 'abcd', 'abcd')

    SET @AddressID = SCOPE_IDENTITY()

    INSERT INTO Users(Name, Age, AddressID)
    VALUES (@Name, 20, @AddressID)
    FETCH NEXT FROM UserCursor INTO @ID, @Name
END
CLOSE UserCursor
DEALLOCATE UserCursor
于 2012-05-24T18:10:33.820 に答える
2

これは少しハックですが、2 つのステートメントで必要なことを行います。「abcd」という名前を持っているか、国の名前を入力するユーザーがいないと仮定し、この操作の後に NewUsers テーブルを消去するとします。

INSERT dbo.Addresses(Country, State, City, ZipCode)
OUTPUT inserted.Country, 20, inserted.id
INTO dbo.Users
SELECT Name, 'abcd', 'abcd', 'abcd'
FROM dbo.NewUsers;

UPDATE a SET Country = 'abcd'
FROM dbo.Addresses AS a
INNER JOIN dbo.NewUsers AS nu
ON a.Country = nu.Name;
于 2012-05-24T16:33:17.007 に答える
0

正直なところ、答えはあなたがやりたいと思うことをしたくないということです。あなたが述べたように、ユーザーが唯一のアドレスを持っている場合、アドレスフィールドを含むテーブル(ユーザー)は1つだけでなければなりません。データを適切にモデル化すると、この問題は本質的に解消されます。

于 2012-05-24T18:32:22.393 に答える
0

必要に応じて AddressId を設定できると仮定します...

INSERT Addresses
(
    Id,
    Country,
    State,
    City,
    ZipCode
)
SELECT
    Id,
    'abcd',
    'abcd',
    'abcd',
    'abcd'
FROM NEWUsers

INSERT Users
(
    Id,
    Name,
    Age,
    AddressId
)
SELECT
    Id,
    Name,
    20,
    Id
FROM NEWUsers

AddressId が ID 列である場合は、まず ID を一時的に無効にすることができます。情報と例については、 SET IDENTITY_INSERTを参照してください。

于 2012-05-24T16:21:28.133 に答える