[devmedia .net]
09/04/2009
Opa, blz ?
Para fazer um case no sql é simples utilize o exemplo que eu fiz abaixo:
DECLARE @Categoria int
SELECT @Categoria = Type FROM schSell.Categories WHERE (Identity = @Identity) AND (Show = 'T') AND (Language = @Language) )
SELECT
CASE @Categoria
-- Quando o valor for igual
WHEN 'E' THEN
SELECT DISTINCT Experience,Id FROM schSell.Product WHERE UPPER(Show) = 'T' AND Identity = @Identity AND (Language = @Language) AND (Id = @Id) ORDER BY Experience
WHEN 'X' THEN
Faça outra coisa e etc...
WHEN 'Y' THEN
Faça outra coisa e etc...
ELSE
Faça outra coisa
END
Abraços
Carlos Jr
GOSTEI 0
Régis Mello
09/04/2009
Oi Carlos,
Entendi, mas acho que estou fazendo algo erro, olha só a mensagem que aparece....
Mensagem 116, Nível 16, Estado 1, Procedimento SELECT_SUBCATEGORIES_GIFT, Linha 33
Somente uma expressão pode ser especificada na lista de seleção quando a subconsulta não é introduzida com EXISTS.
Mensagem 116, Nível 16, Estado 1, Procedimento SELECT_SUBCATEGORIES_GIFT, Linha 43
Somente uma expressão pode ser especificada na lista de seleção quando a subconsulta não é introduzida com EXISTS.
Mensagem 116, Nível 16, Estado 1, Procedimento SELECT_SUBCATEGORIES_GIFT, Linha 50
Somente uma expressão pode ser especificada na lista de seleção quando a subconsulta não é introduzida com EXISTS.
Outra coisa como eu coloco no ELSE uma mensagem, já que nenhum tipo do CASE foi acionado quero colocar uma mensagem
TIPO de categoria não encontrada.
ALTER PROCEDURE [schSell].[SELECT_SUBCATEGORIES_GIFT]
(
@Identity NVARCHAR(50),
@Language INT,
@Id int
)
AS BEGIN
DECLARE @Type int
SELECT @Type = Type
FROM Categories
WHERE (Identifity = @Identity)
AND (Show = 'T')
AND (Language = @Language)
SELECT
CASE @Type
-- Quando o valor for igual
WHEN 'E' THEN
(
SELECT DISTINCT Experience, Id
FROM Products
WHERE UPPER(Show) = 'T'
AND (Identifity = @Identity)
AND (Language = @Language)
AND (Id = @Id)
)
WHEN 'G' THEN
(
SELECT Id,Title
FROM vieCategories
WHERE (Identifity = @Identity)
AND (Show = 'T')
AND (Type = 'P')
AND (Language = @Language)
)
ELSE (
AQUI EU QUERO COLOCAR UMA MENSAGEM QUE NENHUM TIPO FOI ENCONTRATO.
)
END
END
ACHO QUE EU ESTOU ERRANDO OS (), MAS NÃO TENHO CERTEZA.
TENTEI FAZER UM ORDER BY, MAS A STORED PROCEDURE TAMBÉM NAO ACEITA.
Valew
Regis
GOSTEI 0
[devmedia .net]
09/04/2009
Ólá Régis, tudo bem ?
Gostaria que você me enviasse o script das tabelas envolvidades nos seus selects,
para que eu posso simular o código.
Fico no aguardo..
Abraços
Carlos Jr
GOSTEI 0
Régis Mello
09/04/2009
Boa noite Carlos Junior, não consegui anexar um arquivo, por isso postei em um servidor que uso para fazer meus testes, http://189.126.109.105/Carlos/ lá será possível encontrar as duas tabelas envolvidas, e um exemplo de como as tabelas são preenchidas.
Também postarei aqui o código para ajudar caso tenha restrições em acessar um site de terceiros sem conhecer.
Bom o que eu preciso fazer eu expliquei mas, nunca é demais obter informações.
Existem tipos de categorias , P, G, O, E , cada tipo starta uma nova consulta, então eu preciso primeiro usando o Identity e Id selecionar qual o tipo de categoria, depois efetuar as novas consultas, ou seja, se a categoria pesquisa retornar um type do tipo E, eu tenho que pesquisar na tabela proplan e retornar o campo Experience, que é o local, ou seja, SP, RJ, BA, e assim vai, se o tipo é G, entao eu tenho que pesquisar na tabela categories todas as categoria tipo P, ou seja, produtos , eletrônicos, eletrodomésticos, é como se montasse uma subcategoria.
E Se não retornar nenhum desses tipos, nesse caso responder que o tipo é inválido e assim da consulta.
Sei que é uma consulta simples, mas o fato é que apesar de já ter evoluido muito ainda tem muito para aprender, já consigo até exportar e importar dados, aprendi fazer aquelas consultas com duas tabelas, mas estou gostando muito de poder contar com ajuda de profissionais na hora das dúvidas.
Essa consultoria venho em excelente hora, parabéns pela Idéia.
Qualquer dúvida é só perguntar.
Lá vai o código:
CREATE TABLE [dbo].[Categories](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Identity] [nvarchar](50) NOT NULL,
[Show] [nchar](1) NOT NULL,
[Soon] [nvarchar](50) NULL,
[Title] [nvarchar](20) NOT NULL,
[Language] [nchar](5) NOT NULL,
[Type] [nchar](1) NOT NULL,
[Link] [nvarchar](255) NULL,
[ImgCategory] [nvarchar](100) NULL,
CONSTRAINT [PK_vieCategories] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
_________________________________________________________________________
CREATE TABLE [dbo].[ProPlan](
[IdPro] [bigint] IDENTITY(1,1) NOT NULL,
[Id] [int] NOT NULL,
[Identity] [nvarchar](50) NOT NULL,
[Reference] [nchar](2) NOT NULL,
[Model] [nvarchar](255) NOT NULL,
[Summary] [nvarchar](255) NOT NULL,
[Details] [text] NULL,
[Features] [text] NULL,
[Manual] [nchar](1) NULL,
[LinkInclude] [nvarchar](100) NULL,
[Size] [nvarchar](50) NULL,
[Weight] [nvarchar](50) NULL,
[Garantee] [nvarchar](255) NOT NULL,
[TimeDelivery] [nvarchar](255) NULL,
[StartDate] [nvarchar](50) NULL,
[PostDate] [date] NULL,
[Img1] [nvarchar](100) NULL,
[Img2] [nvarchar](100) NULL,
[Img3] [nvarchar](100) NULL,
[Local] [nvarchar](150) NULL,
[Experience] [nvarchar](255) NULL,
[Price] [decimal](8, 2) NOT NULL,
[PriceSetup] [decimal](8, 2) NOT NULL,
[Recharge] [decimal](8, 2) NULL,
[PriceDiscount] [decimal](8, 2) NULL,
[PointPurchase] [decimal](9, 0) NOT NULL,
[Type] [nchar](1) NULL,
[Show] [nchar](1) NOT NULL,
CONSTRAINT [PK_ProPlan] PRIMARY KEY CLUSTERED
(
[IdPro] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[ProPlan] WITH CHECK ADD CONSTRAINT [FK_ID] FOREIGN KEY([Id])
REFERENCES [dbo].[Categories] ([Id])
GO
ALTER TABLE [dbo].[ProPlan] CHECK CONSTRAINT [FK_ID]
GO
ALTER TABLE [dbo].[ProPlan] WITH CHECK ADD CONSTRAINT [CK_MANUAL] CHECK (([Manual]='T' OR [Manual]='F'))
GO
ALTER TABLE [dbo].[ProPlan] CHECK CONSTRAINT [CK_MANUAL]
GO
ALTER TABLE [dbo].[ProPlan] WITH CHECK ADD CONSTRAINT [CK_Show] CHECK (([Show]='T' OR [Show]='F'))
GO
ALTER TABLE [dbo].[ProPlan] CHECK CONSTRAINT [CK_Show]
GO
ALTER TABLE [dbo].[ProPlan] WITH CHECK ADD CONSTRAINT [CK_TYPEPRO] CHECK (([Type]='G' OR [Type]='E' OR [Type]='P' OR [Type]='L'))
GO
ALTER TABLE [dbo].[ProPlan] CHECK CONSTRAINT [CK_TYPEPRO]
GO
-_____________________________________________________________________________
Valew
Regis
GOSTEI 0
[devmedia .net]
09/04/2009
Olá Régis, tudo bem ?
Cara, me desculpe mas as coisas não estão legais, está faltando alguma informação ou tem algo errado no que me falou...
Quero muito lhe atender e tenho muita boa vontade, acabo de passar 3 horas analisando e testando sua procedure junto com as tabelas que me enviou, mas ainda está confuso.
Veja algumas observações ( no final da resposta tem uma dica ):
-> Você não pode utilizar nome de colunas de tabela com as palavras resevadas do banco de dados, por exemplo [Identity] [nvarchar](50) NOT NULL Identity não pode ser utilizado,
favor alterar o nome de sua coluna, isso é um dos erros.
Ou, você deve usar obrigatóriamente [] no nomes das colunas que contém palavras reservadas.
-> Products, que tabela é essa ?
Você não me enviou...
Veja na sua procedure.
-> Você declarou errado o parâmetro @Type int , mas não é inteiro é char
DECLARE @Type char(2)
-> Estou achando muito confuso, pois tem muita coisa errada na procedure,
nome de campos, chamando tabelas que não existe Products por exemplo
-> Estou lhe enviando a procedure de novo alterada, compilando certinho,
mas não sei se te atenderá pois como falei está muito confuso
->Nos selects dentro do case, deve ser retornado o mesmo número e tipo de colunas declaradas no select antes do case.
Segue a procedure alterada...
ALTER PROCEDURE SELECT_SUBCATEGORIES_GIFT
(
@Identity NVARCHAR(50),
@Language INT,
@Id int
)
AS
BEGIN
DECLARE @Type char(2)
SELECT @Type = [Type]
FROM Categories
WHERE ([Identity] = @Identity)
AND (Show = 'T')
AND ([Language] = @Language)
SELECT campo =
CASE @Type
WHEN 'G' THEN
(
SELECT Id as campo
FROM Categories
WHERE ([Identity] = @Identity)
AND (Show = 'T')
AND ([Type] = 'P')
AND ([Language] = @Language)
)
-- Para repetir os case´s copie a parte de cima e cole abaixo MODIFICANDO do jeito que precisar
-- Deve ser prestar atenção no nome dos campos e as tabelas, pois estão muito errados
-- Veja que as consultas sempre retornam o mesmo número de campos do select case
WHEN 'E' THEN
(
SELECT DISTINCT Experience as campo
FROM ProPlan
WHERE UPPER(Show) = 'T'
AND ([Identity] = @Identity)
AND (Id = @Id)
)
ELSE
(
-- Retorne Zero como nenhum tipo encontrado
-- No código você trata o retorno
SELECT 0 campo
)
END
END
Posso lhe dar uma dica ?
Por que não faz isso pelo código cara ?
Fazer isso utilizando recursos do banco com case, if e etc deixa mais lenta a consulta,
eu não indico fazer isso no banco, e sim fazer via código.
Se quiser fazer via código me fale , que eu faço uma lógica para você, que é bem mais fácil.
Aguardo seu retorno,
Abraços
Carlos Jr
GOSTEI 0
Régis Mello
09/04/2009
Boa tarde,
De fato não efetua a consulta e dá um erro, vou trabalhar nas tabelas e amanhã te envio ela reorganizado conforme você me explicou.
Não é possível fazer no código não, estou aprendendo TRANSACT-SQL a idéia é ir aperfeiçoando, se não me esforçar para entender como faço isso agora, quando precisar não saberei fazer, pensando na sua idéia de poupar o Banco tive uma idéia, já que as storedprocedure são consultadas pelo webservice, e eu uso diversas procedures nas consultas, eu poderia fazer uma procedure que retornaria o tipo e a seguir um when dentro dessa procedure para executar outras procedures? Assim poderia usar as procedures dentro do When, mesmo que não estivem ligadas ao retorno do tipo.
O que acha?
Cordialmente
Regis
GOSTEI 0
[devmedia .net]
09/04/2009
Opa, tudo bem Régis ...
A idéia é legal.. mas vou te falar de mercado..
Não se utiliza isso que você quer fazer , pois não tem manutenibilidade fácil nisso...
Se for dar manutenção em um lugar terá que sair alterando um monte de lugarers.. e vou te dizer..
isso é a pior coisa que um programador pode fazer..
Devemos desenvolver o mais simples possível, para que fique fácil a manutenção e o entendimento de outras pessoas...
Sinceramente NUNCA vi isso implantando em sistema nenhum, e já tenho um bom tempo de mercado,
mas se quiser fazer assim tudo bem, lhe digo que terá um trabalho muito granda para não utilizar em nenhum momento.
Uma outra dica, tudo que esteja fazendo ficou complicado, tem algo errado.. tudo é muito simples,
pense simples e conseguirá resolver todos os problemas, bem isso é uma dica.
Se fizer no código não quer dizer que não esteja aprendendo sql, e quando colocar isso em prática,
dentro de uma empresa por exemplo , verá que eles utilizam metodologias simples, claro que tudo orientado a objeto, mas é simples.
Estou aqui para lhe ajudar e dar algumas dicas, esse é meu papel.
Espero poder lhe ajudar,
aguardo seu contato para podermos dar continuidade ao seu atendimento.
Grande abraço
Carlos Jr
GOSTEI 0
Devmedia
09/04/2009
Régis,
A resposta do consultor sanou sua dúvida? Podemos encerrar o chamado?
GOSTEI 0
Régis Mello
09/04/2009
Ainda não, fiquei de passar mais dados, mas quando voltei já estava concluído, não sabia que fechava tão rápido.
Fico no aguardo de outro consultor ou reabro o post e solicito outro consultor?
GOSTEI 0
Luiz Maia
09/04/2009
Ola Regis,
Preciso saber o que realmente deseja fazer, estou aguardando.
Abraços
Att
Luiz Maia
GOSTEI 0
Régis Mello
09/04/2009
Voce tem o Banco AdventureWorks2008? Assim podemos usá-lo com leves alterações para explivar, mas se preferir posso encaminhar as tabelas envolvidas. Também estou lendo algumas coisas de SQL para achar a solução, mas veja o que é melhor. Encaminhar as minhas tabelas ou se voce tiver o Adventures talvez facilitaria.
PS: Eu sou Fernanda , esposa do Regis e também estou estudando, mas estou mais avançada que ele.
Achei alguns recursos interessantes que talvez seja melhor que subqueries , mas ainda não apliquei, vou fazer os teste logo mais.
Abraços
Fernanda
GOSTEI 0
Luiz Maia
09/04/2009
Ola Fernando,
Tenho o AdventureWorks2008 sim. Ja pode postar sua duvida aqui, estou aguardando.
Abraços
Att
Luiz Maia
GOSTEI 0
Luiz Maia
09/04/2009
Continuo aguardando sua duvida, ok?
Abraços
Att
Luiz Maia
GOSTEI 0
Devmedia
09/04/2009
Régis / Fernanda,
o consultor está aguardando sua dúvida para poder solucioná-la.
GOSTEI 0
Régis Mello
09/04/2009
Bom dia, desculpa eu viajei e voltei hoje para evitar o transito,
Pode usar a base do AdventureWorks2008 como exemplo na resposta.
Eu precioso criar uma procedure para pegar um resultado (A) , esta procedure será executada dentro de outra PROCEDURE, criar procedure (tudo bem nós sabemos), mas como utilizar o resultado dessa procedure em outra , ainda não sabemos.
- ex:
Preciso passar esse type para ser usado pela Stored Procedure que a chama e executa essa procedure.
ALTER PROCEDURE [schSell].[SELECT_SUBCATEGORIES_GIFT]
(
@Identity NVARCHAR(50), @Language INT,@Id int
)
AS BEGIN
DECLARE @Type int
SELECT @Type = Type
FROM Categories
WHERE (Identifity = @Identity)
AND (Show = 'T')
AND (Language = @Language)
-- Até aqui a procedure base seria criada, depois uma nova procedure iria se alimentar dela para tomar decisões de acordo com o tipo.
-- Em outro exemplo o @IdPartner é chave em diferenças tabelas, por isso teria que ser chamada em diversas procedures para permitir nesse caso uma correta inserção na base de dados. Como demonstrado.
--DECLARE @Identifier nvarchar(50)
DECLARE @IDPARTNER nvarchar(50)
IF NOT EXISTS(SELECT 1 FROM schAdmin.Partners WHERE Identifier = @Identifier)
BEGIN
SELECT 2 AS TIPO, 'PARCEIRO COMERCIAL NÃO ENCONTRADO.' AS MENSAGEM
END ELSE BEGIN
SELECT
@IdPartner = IDPARTNER
FROM schAdmin.Partners WHERE Identifier = @Identifier
O IdPartner precisa ser usado em procedure que invocar essa procedure.
Acho que até aqui eu consegui explicar o porque do procedimento ser necessário.
Agora em diante vou explicar o que preciso fazer em cada caso.
Para primeiro exemplo preciso fazer selects diferentes de acordo com o tipo de categoria encontrado, ou seja, aquele resultado irá motivar os outros resultas, portanto, o procedure que irá consumir a primeira deverá tomar uma decisão.
-- Realizo aqui a primeira consulta que me retorna o Type
Caso retorne o type 'E'
Preciso fazer a pesquisa abaixo:
-- Se retornar um Type = E , essa consulta deve ser executada
SELECT
DISTINCT
Experience,
Id
FROM schSell.Product
WHERE UPPER(Show) = 'T' AND Identity = @Identity
AND (Language = @Language)
AND (Id = @Id)
ORDER BY Experience
END
-- Se retornar um Type = G, preciso fazer essa consulta.
Caso o Type da primeira pesquisa retorne G entao tenho que fazer a seguinte
pesquisa
SELECT
Id,
Title
FROM
schSell.Categories
WHERE
(Identity= @Identity(and
(Show = 'T') AND
(Type = 'P') AND
(Language = @Language)
)
Order by (
Title
)
Eu preciso fazer a consulta de categorias de acordo com o tipo retornado. O campo Type, pode ser P, G ou E.
No entanto novos tipos podem ser acrescentados, portanto, pensaria numa forma que fosse fácil acrescentar mais um ou dois tipos no futuro.
Bom eu acredito que ensinando com passar o parâmetro e tomar decisões as demais eu saberei fazer sozinha.
O Regis está ausente a trabalho, por isso vou ajudá-lo a postar as dúvidas aqui para ele não se atrasar nos estudos, encaminharei as respostas para ele.
Abraços
Fernanda
GOSTEI 0
Luiz Maia
09/04/2009
Ola Regis,
Pelo que entendi de sua duvida, vc precisa chamar uma SP B dentro de outra SP A e usar este retorno para tomar decisões dentro da SP A, correto? Me corriga se eu estiver pensando errado.
Bom sendo isto, segue um exemplos:
O retorno da procedure é uma linha com várias colunas ou uma linha com apenas uma coluna? se for uma linha com apenas uma coluna usar o exemplo abaixo:
Para valores inteiros usar return @variável na procedure que irá retornar o resultado e na procedure que irá receber usar a seguinte síntaxe
EXEC @variavel = procedure @parametro
Para valores diferentes de inteiro eu acho que não da pra receber com um select. Então recomento tb usar variável tipo table . A síntaxe está abaixo no exemplo a seguir.
Se for uma linha com várias colunas pode-se usar tabela temporária ou variável tipo table, o que recomento por se tratar de apenas um registro. A baixo segue também o exemplo:
declare @variavel (@ int, @char, @....) as Table
insert into @variavel (campos)
EXEC procedure @parametro
Lembrando que as colunas da variávels deven ser de número igual ao número de colunas do retorno.
O uso de tabelas temporarias acarretarão numa perda consideravel de performance, ok?
Bem, espero ter ajudado.
Abraços
Att
Luiz Maia
GOSTEI 0
Régis Mello
09/04/2009
Também, mas não somente.
Escrevo amanhã com maiores informações pois hoje estou muito, muito cansado.
O exemplo qu evc mandou eu já tinha encontrado na Internet, mas não funcionou.
Regis
GOSTEI 0
Luiz Maia
09/04/2009
Oi Regis, tudo bom?
Estou aguardando mais detalhes do que vc esta precisando.
Abraços
Att
Luiz Maia
GOSTEI 0
Luiz Maia
09/04/2009
Ola Regis, como não obtivemos resposta, estamos fechando o chamado.
Continuamos a sua disposição.
Abraços
Att
Luiz Maia
GOSTEI 0
Régis Mello
09/04/2009
O que eu preciso fazer é pegar o valor de 1 procedure em 1 outra procedure, vamos fazer essa parte primeiro, depois te envio a segunda parte, entao primeiro vamos pegar o valor de 1 procedure em outra.
IF NOT EXISTS(SELECT 1 FROM schAdmin.Partners WHERE Identifier = @Identifier)
BEGIN
SELECT 2 AS TIPO, 'PARCEIRO COMERCIAL NÃO ENCONTRADO.' AS MENSAGEM
END ELSE BEGIN
SELECT
@IdPartner = IDPARTNER
FROM schAdmin.Partners WHERE Identifier = @Identifier
O valor @IdParter que recebe um inteiro precisa ser passado para outra procedure.
Por exemplo a procedure abaixo: Depois que eu receber esse parametro na outra procedure ficará mais fácil explicar a segunda parte.
ALTER PROCEDURE [schUser].[ADD_UP_EMAIL]
(
@Identifier nvarchar(50),
@UserNum BIGINT,
@Email nvarchar(50),
@EmailFormat NCHAR(10),
@IP nvarchar(20)
)
AS BEGIN
DECLARE @IdPartner int
IF NOT EXISTS(SELECT 1 FROM schAdmin.Partners WHERE Identifier = @Identifier)
BEGIN
SELECT 2 AS TIPO, 'PARCEIRO COMERCIAL NÃO ENCONTRADO.' AS MENSAGEM
END ELSE BEGIN
SELECT
@IdPartner = IDPARTNER
FROM schAdmin.Partners WHERE Identifier = @Identifier
-- Insert EmailAddress in table schUser.EmailAddress
IF EXISTS(SELECT 1
FROM schUser.EmailAddress
WHERE EmailAddress = @Email)
BEGIN
--desfaz inclusões e retorna erro
ROLLBACK
SELECT 2 AS TIPO, 'Email cadastrado' AS MENSAGEM
END ELSE BEGIN
--insere registro relacionado em schUser.EmailAddress
INSERT INTO schUser.EmailAddress
(
IdUser,
IdPartner,
TypeEmail,
ModifiedDate,
EmailAddress,
EmailFormat
)
VALUES (
@UserNum,
@IdPartner,
'S',
GETDATE(),
@Email,
@EmailFormat
)
IF (@@ROWCOUNT = 0) BEGIN
SELECT 2 AS TIPO, 'REGISTRO NÃO REALIZADO.' AS MENSAGEM
END ELSE BEGIN
SELECT 1 AS TIPO, 'INSERIDO COM SUCESSO.' AS MENSAGEM
END
END
UPDATE schUser.EmailAddress
SET
EmailAddress = @Email
,EmailFormat = @EmailFormat
,ModifiedDate = GETDATE()
WHERE
(EmailAddress = @Email)AND
(IdPartner = @IdPartner)
IF (@@ROWCOUNT = 0) BEGIN
SELECT 2 AS TIPO, 'REGISTRO NÃO ENCONTRADO.' AS MENSAGEM
END ELSE BEGIN
SELECT 1 AS TIPO, 'ATUALIZADO COM SUCESSO.' AS MENSAGEM
END
END
END
GOSTEI 0
Luiz Maia
09/04/2009
Regis,
Qual o tipo deste valor que vc quer pegar de uma procedure na outra? Uma string? Inteiro? RecordSet?
GOSTEI 0
Régis Mello
09/04/2009
Conforme escrevi no post anterior , o @IdPartner recebe um inteiro (int).
Regis
GOSTEI 0
Luiz Maia
09/04/2009
Regis,
Para isto vc devera ter uma prcedure com parametros output, segue exemplo abaixo. Se baseie nele para alterar a sua.
1 - Primeira SP, repare no parametro @Num_Proposta que é passado para a segunda SP via output, asssim o valor "volta"
DECLARE @NUM_PROPOSTA AS INTEGER
EXEC INTRANETBMB..SP_IBuscaNroProposta @CARTEIRA_PROPOSTA, @SUB_CARTEIRA_PROPOSTA, 'N', @NUM_PROPOSTA OUTPUT
2 - Segunda SP:
ALTER PROCEDURE SP_IBuscaNroProposta
@Cod_Carteira AS INTEGER,
@Cod_SubCarteira AS INTEGER,
@Flag_Form_Eletronico AS CHAR(1),
@Num_Proposta AS INTEGER OUTPUT
AS
BEGIN ..........
Caso não entenda algo, me avise.
Abraços
Att
Luiz Maia
GOSTEI 0
Régis Mello
09/04/2009
Essa é a primeira procedure, note que ela tem um if exists ( Isso é obrigatório ), fiz isso abaixo:
ALTER PROCEDURE [dbo].[FIND_IDPARTNER]
(
@Identifier nvarchar(50)
)
AS
BEGIN
DECLARE @IdPartner int
IF NOT EXISTS(SELECT 1 FROM schAdmin.Partners WHERE Identifier = @Identifier)
BEGIN
SELECT 2 AS TIPO, 'PARCEIRO COMERCIAL NÃO ENCONTRADO.' AS MENSAGEM
END ELSE BEGIN
SELECT
@IdPartner = IDPARTNER
FROM schAdmin.Partners WHERE Identifier = @Identifier
EXEC dbo.FIND_IDPARTNER @IdPartner OUTPUT Preciso passar esse parametro para a proxima procedure, mas ele não vai. Copiei o código aqui, mas acho que tem algo errado , pois nao funciona.
END
END
GOSTEI 0
Luiz Maia
09/04/2009
O parametro de entrada tb deve ser output:
@Identifier nvarchar(50)
E não pode ser nvarchar(50), como me falou que era um inteiro!!!!!
Abraços
Att
LUiz Maia
GOSTEI 0
Régis Mello
09/04/2009
Vc leu a consulta?
O @Identifier é usado para localizar o @IdPartner , o @Identifier não será usado na próxima procedure, apenas o @IdPartner que irá receber um int como já falei nas últimos dois post. A Consulta é para retornar caso o parceiro não exista, e o campo postado pelo parceiro é uam chave com 32 caracteres alfa numérico. Essa chave será usada para fazer uma consulta e retorna um @IdPartner que será inteiro.
Regis
GOSTEI 0
Luiz Maia
09/04/2009
Regis, vc precisa deste parametro nas duas procedures, caso queira recuperar algum valor, pois este parametro é um OUTPUT, usado para transpassar valores entre procedures. Sem ele não tem como fazer o que vc quer!!!
É como se vc passase um parametro vazio para a SP, esta parametro fosse populado dentro da sp, e depois vc recuperaria ele fora dela, que no seu caso é outra SP.
GOSTEI 0
Devmedia
09/04/2009
Régis / Fernanda,
conseguiu solucionar o problema?
GOSTEI 0
Devmedia
09/04/2009
Régis / Fernanda,
por falta de retorno, estamos concluindo o chamado. so ainda tenham dúvidas sobre o assunto do mesmo, por favor, poste aqui q o consultor voltará a lhes atender.
GOSTEI 0
Régis Mello
09/04/2009
Prezados
Por favor leiam o que eu escrevi, tentei ser o mais clara possível, o Identifier é de fato e sempre será um nvarchar, o IdPartner é um Int, pois é uma chave primária da tabela, nunca eu receberei o Identifier, já fiz o código para pegar o @IdPartner, mas eu quero chamar esse código de outra procedure e executar pegando o valor do @IdPartner
Ainda não foi possível eu criar o código o que eu preciso e muito simples, sei que é possível ser feito, no entanto, no atual momento eu não sei como fazê-lo.
Tentei fazer o que você passou, mas o Identifier é o código nvarchar usado para localizar o IdPartner, portanto, não vou ter o @IdPartner como entrada, apenas como saida, nunca como entrada.
Eu utilizo um trecho de código em várias procedures, como mostro abaixo:
ALTER PROCEDURE [schUser].[LOGIN]
(
@UserNum bigint,
@Password nvarchar(128),
@Identifier nvarchar(50),
@IP nvarchar(20)
) AS BEGIN
-- o TRECHO ABAIXO EU USO EM DIVERSAS PROCEDURES, POR ISSO DESEJO CRIAR UMA PROCEDURE EXTERNA E EXECUTAR ESSA PROCEDURE NAS DEMAIS PROCEDURES SEM A NECESSIDADE DE REPLICAR O CÓDIGO TODAS AS VEZES QUE NECESSITAR LOCALIZAR O @IdPartner.
DECLARE @IdPartner int
IF NOT EXISTS(SELECT 1 FROM schAdmin.Partners WHERE Identifier = @Identifier)
BEGIN
SELECT 2 AS TIPO, '100' AS MENSAGEM
END ELSE BEGIN
SELECT
@IdPartner = IDPARTNER
FROM schAdmin.Partners WHERE Identifier = @Identifier
-- Search password
IF NOT EXISTS(
SELECT 1
FROM schUser.[Password]
WHERE (IdUser = @UserNum) AND
([Password] = @Password)
)
BEGIN
SELECT 2 AS TIPO, 'Senha incorreta.' AS MENSAGEM
END ELSE BEGIN
SELECT 3 AS TIPO, '1' AS MENSAGEM
END
END
END
________________________________________________________________________________________
Segue abaixo outro exemplo de procedure onde obrigatoriamente eu preciso conseguir o IdPartner, e de fato estou conseguindo pegá-lo, mas fico replicando o código dentro de todas as procedures, quero fazer uma procedure e chamar essa procedure e executar dentro das procedures que eu preciso.
CREATE PROCEDURE [schUser].[SELECT_USER]
(
@UserNum bigint,
@Identifier nvarchar(50)
) AS BEGIN
--DECLARE @Identifier nvarchar(50)
DECLARE @IdPartner INT
IF NOT EXISTS(SELECT 1 FROM schAdmin.Partners WHERE Identifier = @Identifier)
BEGIN
SELECT 2 AS TIPO, '100' AS MENSAGEM
END ELSE BEGIN
SELECT
@IdPartner = IDPARTNER
FROM schAdmin.Partners WHERE Identifier = @Identifier
--inicia transação para possibilitar
IF EXISTS(SELECT 1 FROM schUser.Users WHERE (IdUser = RTRIM(LTRIM(@UserNum))))
--SE EXISTE USUÀRIO NO BANCO PARA ESTE @Identifier
BEGIN
SELECT schUser.EmailAddress.TypeEmail,
schUser.EmailAddress.IdEmail,
schUser.EmailAddress.EmailAddress,
schUser.EmailAddress.EmailFormat,
schUser.Users.DocNum,
schUser.Users.Title,
schUser.Users.FirstName,
schUser.Users.MiddleName,
schUser.Users.LastName,
schUser.Users.Birth,
schUser.Users.Sex,
schUser.Users.Activated,
schMarkt.PlanMarketing.NameLicense,
schMarkt.PlanMarketing.[Status]
FROM schUser.EmailAddress INNER JOIN
schUser.Users ON schUser.EmailAddress.IdUser = schUser.Users.IdUser INNER JOIN
schMarkt.PlanMarketing ON schUser.Users.IdPlan = schMarkt.PlanMarketing.IdPlan
WHERE (schUser.EmailAddress.IdUser = @UserNum) AND (schUser.EmailAddress.IdPartner = @IdPartner) AND (schMarkt.PlanMarketing.Activated = 'T')
END ELSE BEGIN
SELECT 2 AS TIPO, '102' AS MENSAGEM
END
END
END
GOSTEI 0
Luiz Maia
09/04/2009
Regis, como eu ja disse:
vc precisa deste parametro nas duas procedures, caso queira recuperar algum valor, pois este parametro TEM QUE SER OUTPUT, usado para transpassar valores entre procedures. Sem ele não tem como fazer o que vc quer!!!
É como se vc passase um parametro vazio para a SP, esta parametro fosse populado dentro da sp, e depois vc recuperaria ele fora dela, que no seu caso é outra SP.
Aguardo.
Luiz Maia
GOSTEI 0
Régis Mello
09/04/2009
ok, nao ajudou muito, mas estou pesquisando na Internet e já estou conseguindo fazer.
GOSTEI 0
Luiz Maia
09/04/2009
Regis,
Estou percebendo que vc não esta endentendo o que estou te falando pra fazer.
Entendi o que vc quer fazer e ja fiz aqui, mas para isto vc precisa usar um parametro OUTPUT, que transportará um valor de uma SP para outra e depois vc consegue recuperar ela na SP que vc esta chamando a outra.
Caso não consiga ainda, me avisa que faço um pequeno video pra vc ou monto um exemplo aqui de script e te mando via Disco Virtual, blz?
Aguardo um retorno de vc.
Abraços
Att
Luiz Maia
GOSTEI 0
Régis Mello
09/04/2009
Fiz aqui com o OUTPUT , mas ele diz que eu tenho que receber um int, eu não recebo um int, se recebesse seria mais fácil, mas eu não recebo, recebo uma string com 32 caracteres que nunca se repetem, isso é o que eu recebo, preciso pegar o Id do Parceiro para cadastrar nas outras tabelas que eu criei com um CONSTRAINT que verifica se o Id existe na tabela de referência para manter a consistência do Banco. Por isso preciso pesquisar na tabela Partner.
Me avisa como posso receber esse exemplo ou video.
Att
Regis
GOSTEI 0
Luiz Maia
09/04/2009
Ola, vou fazer primeiro um exemplo de script, ai te mando e vc testa ai. Caso ainda sim nao consiga, faço um pequeno video pra vc, ok? Tem como me mandar o script de sua base de dados, somente das tabelas pertinentes ao problema? e suas Sps tb?
Aguardo.
Att
Luiz Maia
GOSTEI 0
Luiz Maia
09/04/2009
Vamos la Regis, segue os passos ai que vc vai enteder o procedimento todo, vamos por parte.
Vamos simular uma nova situação, somente para efeito de didatica, ok.
1 - Primeiro crie um novo banco de dados com nome "DevMedia".
2 - Execute este script de criação de uma tabelinha "produto":
USE [DevMedia]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[produto](
[cod_produto] [int] IDENTITY(1,1) NOT NULL,
[dsc_produto] [varchar](50) COLLATE Latin1_General_CI_AS NOT NULL,
[vlr_produto] [money] NOT NULL,
[cod_registro] [varchar](15) COLLATE Latin1_General_CI_AS NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
3 - Execute este script para criarmos um registro na base: Veja que temos um campo no qual vamos incluir um texto com 15 carateres, como abaixo.
insert into produto(dsc_produto, vlr_produto, cod_registro) values ('teste', 1000, 'aquitem15caract')
4 - Crie a SP que sera a SP que retornara um dado que vc quiser, para nao precisar ficar usando o mesmo trecho de codigo toda hora em varias SPs. Nesta que criei tenho somente um select ficticio que faz de conta que retornou o valor da chave que acabamos de incluir na tabela, ou seja, é a mesma chave:
create procedure sp_retorna_um_valor
@dsc_valor AS varchar(15) OUTPUT
as
begin
SELECT @dsc_valor = 'aquitem15caract'
End
5 - Agora crie uma outra SP que ira "reaproveitar" o codigo, ou seja, fara uma chamada à SP acima que acabamos de criar: (Veja que na SP abaixo, tenho um parametro criado dentro dela inicialmente vazio, que é passado para a sp_retorna_um_valor vazio, o mesmo é populado dentro dela com o texto que ela retorna, e voltara para a SP abaixo ja populado com valor, assim, o parametro @variavel abaixo, que antes era vazio, depois que passamos ele para a outra SP via output, ele se tornou não mais vazio e agora tem dados dentro dele, assim pode ser usado para outros fins. Abaixo usei para verificar uma clausula no SELECT)
alter procedure sp_usa_outra_sp_dentro_desta
as
begin
declare @variavel as varchar(15)
set @variavel = ''
exec sp_retorna_um_valor @variavel output
select * from produto where cod_registro = @variavel
end
6 - Por ultimo, para verificar se esta tudo ok, basta executar o seguinte comando, ou seja uma chamada à SP acima:
exec sp_usa_outra_sp_dentro_desta
Agora, com este script não tem como dar errado, pois testei exaustivamente aqui em minha maquina.
Espero ter ajudado e estou aguardando um retorno seu.
Abraços
Att
Luiz Maia
GOSTEI 0
Régis Mello
09/04/2009
entendi, vou testar amanhã a tarde e te retorno até as 19:00 H , ok?
Att
Regis
GOSTEI 0
Devmedia
09/04/2009
Lorena,
aconselho a utilizar o firefox ou I.E.
depois que vc chegar no caixa de seleção de imagem, vc deve escolher a
imagem. Deve aparecer uma mensagem no canto superior esqerdo dizendo que a imagem foi
upada. Depois escolha a mesma e clique em ok.
Se tiver problemas, assita ao video para responder um chamado com texto.
GOSTEI 0
Luiz Maia
09/04/2009
Desculpe Regis, o post abaixo foi por engano para você, por favor ignore-o.
Grato
Att
Luiz Maia
GOSTEI 0
Régis Mello
09/04/2009
Boa noite,
até um determinado pouco eu consegui fazer, mas nao consigo passar o IdPartner para outra procedure, ele não vai entrar esse Id é resultado de uma consulta.
Estou passando o script.
USE [Ecommerce]
GO
/****** Object: StoredProcedure [dbo].[SELECT_SUMMARY] Script Date: 05/11/2009 19:52:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SELECT_SUMMARY]
@Identifier AS nvarchar(50) OUTPUT
as begin
--EXEC RETURN_IDPARTNER @Identifier
declare @IdPartner as int
declare @variavel as int
set @variavel = @IdPartner
exec RETURN_IDPARTNER @Identifierr output
select * from schAdmin.Partners where IdPartner = @IdPartner (aqui retorna nulo)
end
USE [Ecommerce]
GO
/****** Object: StoredProcedure [dbo].[RETURN_IDPARTNER] Script Date: 05/11/2009 19:45:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[RETURN_IDPARTNER]
@Identifier AS nvarchar(50) OUTPUT
as
begin
DECLARE @IdPartner as int
-- Search partners
IF NOT EXISTS(SELECT 1 FROM schAdmin.Partners WHERE Identifier = @Identifier)
BEGIN
SELECT 2 AS TIPO, '100' AS MENSAGEM
END ELSE BEGIN
SELECT
@IdPartner = IDPARTNER
FROM schAdmin.Partners WHERE Identifier = @Identifier
select * from schAdmin.Partners where IdPartner = @IdPartner
END
END
Regis
GOSTEI 0
Luiz Maia
09/04/2009
Ola Regis,
Vc seguiu o script que te passei? Fex exatamente todos os passos?
E ainda sim não funcionou?
Por favor, siga a rotina que te enviei, que funciona perfeitamente, depois vc vendo funcionar vai ter uma ideia melhor e depois podera transpor o script para sua aplicação alterando-a.
Aguardo um retorno seu
Att
Luiz Maia
GOSTEI 0
Régis Mello
09/04/2009
eu fiz, ela funciona até o momento que o valor esta dentro da procedure, quando eu passo o valor pelo sistema ainda nao funciona.
Vou continuar tentando.
Regis
GOSTEI 0
Régis Mello
09/04/2009
eu fiz, ela funciona até o momento que o valor esta dentro da procedure, quando eu passo o valor pelo sistema ainda nao funciona.
Vou continuar tentando.
Regis
GOSTEI 0
Luiz Maia
09/04/2009
Regis,
Como assim passa o valor pelo sistema?
Me mande o codigo que te mandei alterado para o que precisa e esta fazendo que esta dando erro.
Assim posso entender melhor.
Aguardo
Abraços
Att
Luiz Maia
GOSTEI 0
Luiz Maia
09/04/2009
E ai Regis, como esta indo?
Aguardo um retorno seu.
Abraços
Att
Luiz Maia
GOSTEI 0
Luiz Maia
09/04/2009
Ola Regis,
Como não obtivemos retorno estamos concluindo o chamado. Se caso ainda houver alguma duvida, nos contacte novamente.
Abraços
Att
Luiz Maia
GOSTEI 0