Inserir registo em tabela com chave estrangeira
Olá.
Estou com uma dúvida na inserção em uma tabela.
Tenho a tabela Cliente com o atributo IdCodPostal, que é chave estrangeira para a tabela CodPostal.
A tabela CodPostal tem como chave primária IdCodpostal. Tem ainda mais um atributo, Localidade.
Ao inserir um Cliente, quando for preencher o campo IdCodPostal esse valor já teve estar incluido na tabela CosPostal, pois é uma chave estrangeira.
Mas o que eu queria era que quando cadastrasse um Cliente pudesse preencher o campo IdCodPostal e Localidade. Mas como Localidade é atributo de outra tabela não sei bem como fazer. Além disso queria que, ao cadastrar, se o valor de IdCodPostal não estivesse na tabela CodPostal ele fosse automaticamente inserido lá, bem como a respetiva Localidade.
Obrigado
Estou com uma dúvida na inserção em uma tabela.
Tenho a tabela Cliente com o atributo IdCodPostal, que é chave estrangeira para a tabela CodPostal.
A tabela CodPostal tem como chave primária IdCodpostal. Tem ainda mais um atributo, Localidade.
Ao inserir um Cliente, quando for preencher o campo IdCodPostal esse valor já teve estar incluido na tabela CosPostal, pois é uma chave estrangeira.
Mas o que eu queria era que quando cadastrasse um Cliente pudesse preencher o campo IdCodPostal e Localidade. Mas como Localidade é atributo de outra tabela não sei bem como fazer. Além disso queria que, ao cadastrar, se o valor de IdCodPostal não estivesse na tabela CodPostal ele fosse automaticamente inserido lá, bem como a respetiva Localidade.
Obrigado
Maria Araújo
Curtidas 0
Respostas
João Françozo
08/05/2014
Bom dia Maria,
A sua estrutura esta correta, você quer informar ao usuário o nome da localidade, para fazer isso tem que fazer um select quando o usuário seleciona o IdCodpostal da chave estrangeira e exibir no campo para visualização.
Dessa forma você não vai ter anomalias de dados.
Exemplo.
select * from CodPostal where IdCodpostal=:IdCodpostal
Att
João Antonio
A sua estrutura esta correta, você quer informar ao usuário o nome da localidade, para fazer isso tem que fazer um select quando o usuário seleciona o IdCodpostal da chave estrangeira e exibir no campo para visualização.
Dessa forma você não vai ter anomalias de dados.
Exemplo.
select * from CodPostal where IdCodpostal=:IdCodpostal
Att
João Antonio
GOSTEI 0
Maria Araújo
08/05/2014
Mas imagine que eu estou a cadatrar o Cliente A.
Introduzo os seus dados e ele tem CodPostal AAAA e Localidade BBBB.
Se este registo de CodPostal não estiver já inserido na tabela CodPostal, vou ter um erro, por causa da chave estrangeira.
Eu penso que devo fazer uma procedure para inserir Cliente e, quando preencher o IdCodPostal no Cliente tenho de ir confirmar à tabela CodPostal se esse IdCodPostal já está inserido ou não.
Se já estiver não há problema.
O problema é se o IdCodPostal AAAA não está na tabela CodPostal.
Devo criar um trigger para quando inserir um IdCodPostal, que não esteja na Tabela CodPostal, ele chame a procedure de inserir CodPostal, com IdCospPostal e Localidade?
Acho que está um pouco confuso não?
Introduzo os seus dados e ele tem CodPostal AAAA e Localidade BBBB.
Se este registo de CodPostal não estiver já inserido na tabela CodPostal, vou ter um erro, por causa da chave estrangeira.
Eu penso que devo fazer uma procedure para inserir Cliente e, quando preencher o IdCodPostal no Cliente tenho de ir confirmar à tabela CodPostal se esse IdCodPostal já está inserido ou não.
Se já estiver não há problema.
O problema é se o IdCodPostal AAAA não está na tabela CodPostal.
Devo criar um trigger para quando inserir um IdCodPostal, que não esteja na Tabela CodPostal, ele chame a procedure de inserir CodPostal, com IdCospPostal e Localidade?
Acho que está um pouco confuso não?
GOSTEI 0
Jair N.
08/05/2014
Bom Dia, não tem como, você deverá fazer a inclusão na tabela de relacionamento para depois, ai sim preencher a sua principal para não ter registros "órfãos" dando erro de chave não encontrada, faça um procedimento primeiro de inclusão nas tabelas de relacionamento, após esse procedimento não terá mais problemas, caso contrário sua segunda opção será criar um processo com os procedimentos de pesquisa de: se, caso não tiver sido cadastrado na tabela de relacionamento, "faça" o cadastro é "retorne" ao procedimento de "inclusão" dos registros.
Atc.
Atc.
Mas imagine que eu estou a cadatrar o Cliente A.
Introduzo os seus dados e ele tem CodPostal AAAA e Localidade BBBB.
Se este registo de CodPostal não estiver já inserido na tabela CodPostal, vou ter um erro, por causa da chave estrangeira.
Eu penso que devo fazer uma procedure para inserir Cliente e, quando preencher o IdCodPostal no Cliente tenho de ir confirmar à tabela CodPostal se esse IdCodPostal já está inserido ou não.
Se já estiver não há problema.
O problema é se o IdCodPostal AAAA não está na tabela CodPostal.
Devo criar um trigger para quando inserir um IdCodPostal, que não esteja na Tabela CodPostal, ele chame a procedure de inserir CodPostal, com IdCospPostal e Localidade?
Acho que está um pouco confuso não?
Introduzo os seus dados e ele tem CodPostal AAAA e Localidade BBBB.
Se este registo de CodPostal não estiver já inserido na tabela CodPostal, vou ter um erro, por causa da chave estrangeira.
Eu penso que devo fazer uma procedure para inserir Cliente e, quando preencher o IdCodPostal no Cliente tenho de ir confirmar à tabela CodPostal se esse IdCodPostal já está inserido ou não.
Se já estiver não há problema.
O problema é se o IdCodPostal AAAA não está na tabela CodPostal.
Devo criar um trigger para quando inserir um IdCodPostal, que não esteja na Tabela CodPostal, ele chame a procedure de inserir CodPostal, com IdCospPostal e Localidade?
Acho que está um pouco confuso não?
GOSTEI 0
Maria Araújo
08/05/2014
Mas então tenho de povoar a tabela CodPostal antes de inserir um Cliente?
Eu queria que ao cadastrar um Cliente, pudesse cadastrar também o CodPostal e Localidade em simultâneo.
Eu queria que ao cadastrar um Cliente, pudesse cadastrar também o CodPostal e Localidade em simultâneo.
GOSTEI 0
Jair N.
08/05/2014
Não, conforme eu disse, ou faz o processo em separado, ou vai ter que criar a situação de pesquisa e gravação evitando a tentativa de inserir um registro que não tenha a informação relacionada na sua tabela CodPostal, regra geral.
para isso deverá criar uma procedure de insersão com as cláusulas de SE não encontrar, SE já estiver cadastrado etc...
Atc.
para isso deverá criar uma procedure de insersão com as cláusulas de SE não encontrar, SE já estiver cadastrado etc...
Atc.
Mas então tenho de povoar a tabela CodPostal antes de inserir um Cliente?
Eu queria que ao cadastrar um Cliente, pudesse cadastrar também o CodPostal e Localidade em simultâneo.
Eu queria que ao cadastrar um Cliente, pudesse cadastrar também o CodPostal e Localidade em simultâneo.
GOSTEI 0
Marisiana Battistella
08/05/2014
Você pode fazer tudo isso em um único procedimento...
Este procedimento vai receber as informações a serem incluidas nas duas tabelas. A lógica seria +ou- a seguinte:
1º ) Faz um select para verificar se o código postal existe na tabela CODPOSTAL e retorna o valor em uma variavel
2º ) Cria uma condição para verificar se retornou valor na variável:
* Se a variável estiver vazia, você terá que cadastrar o código postal e, em seguida, se incluiu com sucesso, você inclui o cliente.
* Se retornou valor é porque o código postal já existe na tabela, então você só precisa incluir o cliente.
Utiliza os tratamentos de exceções corretamente que não tem como errar.
Este procedimento vai receber as informações a serem incluidas nas duas tabelas. A lógica seria +ou- a seguinte:
1º ) Faz um select para verificar se o código postal existe na tabela CODPOSTAL e retorna o valor em uma variavel
2º ) Cria uma condição para verificar se retornou valor na variável:
* Se a variável estiver vazia, você terá que cadastrar o código postal e, em seguida, se incluiu com sucesso, você inclui o cliente.
* Se retornou valor é porque o código postal já existe na tabela, então você só precisa incluir o cliente.
Utiliza os tratamentos de exceções corretamente que não tem como errar.
GOSTEI 0
Maria Araújo
08/05/2014
Marisiana, segui o seu conselho e fiz:
CREATE PROCEDURE spInsertClient
@Nome VARCHAR(50),
@IdCodPostal CHAR(8),
@Localidade VARCHAR(20),
@Email VARCHAR(40)
AS
BEGIN
BEGIN TRY
BEGIN TRAN
DECLARE @Res CHAR(8)
SELECT IdCodPostal INTO Res FROM CodPostal WHERE IdCodPostal = @IdCodPostal
IF @Res IS NULL
BEGIN
INSERT INTO CodPostal(IdCodPostal, Localidade) VALUES(@IdCodPostal, @Localidade)
SET @Res = @IdCodPostal;
INSERT INTO Cliente(Nome, IdCodPostal, Email) VALUES(@Nome, @Res, @Email)
END
ELSE
BEGIN
INSERT INTO Cliente(Nome, IdCodPostal, Email) VALUES(@Nome, @IdCodPostal, @Email)
END
SELECT @@IDENTITY AS Retorno
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
SELECT ERROR_MESSAGE() AS Retorno;
END CATCH
END
Se inserir um cliente com um Codigo Postal que não esteja na tabela CodPostal funciona tudo bem.
Mas quando executo a procedure pela 2ª vez, como dados diferentes, obtenho como retorno "There is already an object named 'Res' in the database"
CREATE PROCEDURE spInsertClient
@Nome VARCHAR(50),
@IdCodPostal CHAR(8),
@Localidade VARCHAR(20),
@Email VARCHAR(40)
AS
BEGIN
BEGIN TRY
BEGIN TRAN
DECLARE @Res CHAR(8)
SELECT IdCodPostal INTO Res FROM CodPostal WHERE IdCodPostal = @IdCodPostal
IF @Res IS NULL
BEGIN
INSERT INTO CodPostal(IdCodPostal, Localidade) VALUES(@IdCodPostal, @Localidade)
SET @Res = @IdCodPostal;
INSERT INTO Cliente(Nome, IdCodPostal, Email) VALUES(@Nome, @Res, @Email)
END
ELSE
BEGIN
INSERT INTO Cliente(Nome, IdCodPostal, Email) VALUES(@Nome, @IdCodPostal, @Email)
END
SELECT @@IDENTITY AS Retorno
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
SELECT ERROR_MESSAGE() AS Retorno;
END CATCH
END
Se inserir um cliente com um Codigo Postal que não esteja na tabela CodPostal funciona tudo bem.
Mas quando executo a procedure pela 2ª vez, como dados diferentes, obtenho como retorno "There is already an object named 'Res' in the database"
GOSTEI 0
Fabiano Carvalho
08/05/2014
Acima dessa linha
Coloque essa
Isso faz com que seja verificado se a tabela que está sendo criada exista, caso existir sera dropada.
SELECT IdCodPostal INTO Res FROM CodPostal WHERE IdCodPostal = @IdCodPostal
Coloque essa
if object_id('res','U') is not null drop table res;
Isso faz com que seja verificado se a tabela que está sendo criada exista, caso existir sera dropada.
GOSTEI 0
Maria Araújo
08/05/2014
Funciona perfeitamente.
O problema agora é se insiro um Cliente cujo IdCodPostal já está registado na tabela CodPostal, é o ELSE.
Dá um aviso de que estou inserindo chaves duplicadas.
O problema agora é se insiro um Cliente cujo IdCodPostal já está registado na tabela CodPostal, é o ELSE.
Dá um aviso de que estou inserindo chaves duplicadas.
GOSTEI 0
Fabiano Carvalho
08/05/2014
CREATE PROCEDURE spInsertClient
@Nome VARCHAR(50),
@IdCodPostal CHAR(8),
@Localidade VARCHAR(20),
@Email VARCHAR(40)
AS
BEGIN
BEGIN TRY
BEGIN TRAN
DECLARE @Res CHAR(8)
if object_id('Res','U') is not null
drop table Res;
SELECT IdCodPostal INTO Res FROM CodPostal WHERE IdCodPostal = @IdCodPostal
SET @Res = (select count(*) from Res); --Verifico se possui registros na tabela criada
IF @Res = 0
BEGIN
INSERT INTO CodPostal(IdCodPostal, Localidade) VALUES(@IdCodPostal, @Localidade)
INSERT INTO Cliente(Nome, IdCodPostal, Email) VALUES(@Nome, @Res, @Email)
END
ELSE
BEGIN
INSERT INTO Cliente(Nome, IdCodPostal, Email) VALUES(@Nome, @IdCodPostal, @Email)
END
SELECT @@IDENTITY AS Retorno
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
SELECT ERROR_MESSAGE() AS Retorno;
END CATCH
END
Acho que funciona.
@Nome VARCHAR(50),
@IdCodPostal CHAR(8),
@Localidade VARCHAR(20),
@Email VARCHAR(40)
AS
BEGIN
BEGIN TRY
BEGIN TRAN
DECLARE @Res CHAR(8)
if object_id('Res','U') is not null
drop table Res;
SELECT IdCodPostal INTO Res FROM CodPostal WHERE IdCodPostal = @IdCodPostal
SET @Res = (select count(*) from Res); --Verifico se possui registros na tabela criada
IF @Res = 0
BEGIN
INSERT INTO CodPostal(IdCodPostal, Localidade) VALUES(@IdCodPostal, @Localidade)
INSERT INTO Cliente(Nome, IdCodPostal, Email) VALUES(@Nome, @Res, @Email)
END
ELSE
BEGIN
INSERT INTO Cliente(Nome, IdCodPostal, Email) VALUES(@Nome, @IdCodPostal, @Email)
END
SELECT @@IDENTITY AS Retorno
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
SELECT ERROR_MESSAGE() AS Retorno;
END CATCH
END
Acho que funciona.
GOSTEI 0
Maria Araújo
08/05/2014
Funciona sim.
Também dá se fizer SET @Res = (SELECT * FROM Res);
Quando criei a coluna Email na Tabela Cliente eu especifiquei que era UNIQUE KEY.
Mas se eu executar a procedure sempre com os mesmos dados estou inserido na Tabela Cliente somente linhas repetidas
Também dá se fizer SET @Res = (SELECT * FROM Res);
Quando criei a coluna Email na Tabela Cliente eu especifiquei que era UNIQUE KEY.
Mas se eu executar a procedure sempre com os mesmos dados estou inserido na Tabela Cliente somente linhas repetidas
GOSTEI 0
Maria Araújo
08/05/2014
Culpa minha de inserir repetidos.
Estava mal especificada a UNIQUE KEY.
Estava mal especificada a UNIQUE KEY.
GOSTEI 0