Fórum Cases em procura SQL Server 2008 (Stored Procedure) #4482

09/04/2009

0

BOa tarde, o que eu preciso fazer, é algo simples, mas ainda não sei como fazer, é um case dentro de uma procedure, sendo que primeiro preciso descobrir qual o tipo de categoria tenho registrado no Banco, para isso fiz uma consulta, um select simples que retorna o Type da categoria, depois tenho que fazer novas consultas de acordo com o Type retornado, como se fosse subcategorias, mas não existe uma tabela subcategoria e provavelmente não será necessário, se eu conseguir fazer isso funcionar.     ALTER PROCEDURE [schSell].[SELECT_CATEGORIES_CASES](   Sao os parametros que recebo para a primeira consulta @Identity NVARCHAR(50), @Language INT ) AS ( -- Realizo aqui a primeira consulta que me retorna o Type   SELECT Type FROM schSell.Categories WHERE (Identity = @Identity) AND (Show = 'T') AND (Language = @Language) ) Até aqui tudo bem, mas a partir daqui tenho 3 possibilidades de pesquisa Preciso fazer pesquisas diferentes para cada Type retornado, ou seja, 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 ) E assim vai, tenho outros cases, mas entendo como cria os cases , poderei tentar fazer os outros sozinhos Valew
Régis Mello

Régis Mello

Responder

Posts

09/04/2009

[devmedia .net]

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
Responder

Gostei + 0

09/04/2009

Régis Mello

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
Responder

Gostei + 0

10/04/2009

[devmedia .net]

Ó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
Responder

Gostei + 0

10/04/2009

Régis Mello

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  
Responder

Gostei + 0

11/04/2009

[devmedia .net]

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  
Responder

Gostei + 0

12/04/2009

Régis Mello

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
Responder

Gostei + 0

12/04/2009

[devmedia .net]

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
Responder

Gostei + 0

17/04/2009

Devmedia

Régis,
A resposta do consultor sanou sua dúvida? Podemos encerrar o chamado?
Responder

Gostei + 0

17/04/2009

Régis Mello

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?
Responder

Gostei + 0

17/04/2009

Luiz Maia

Ola Regis,   Preciso saber o que realmente deseja fazer, estou aguardando. Abraços   Att Luiz Maia
Responder

Gostei + 0

18/04/2009

Régis Mello

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
Responder

Gostei + 0

18/04/2009

Luiz Maia

Ola Fernando,   Tenho o AdventureWorks2008 sim. Ja pode postar sua duvida aqui, estou aguardando. Abraços Att Luiz Maia
Responder

Gostei + 0

22/04/2009

Luiz Maia

Continuo aguardando sua duvida, ok? Abraços   Att Luiz Maia
Responder

Gostei + 0

22/04/2009

Devmedia

Régis / Fernanda,
o consultor está aguardando sua dúvida para poder solucioná-la.

Responder

Gostei + 0

23/04/2009

Régis Mello

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      
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar