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
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
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
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
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
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
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
Régis,
A resposta do consultor sanou sua dúvida? Podemos encerrar o chamado?
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?
Ola Regis,
Preciso saber o que realmente deseja fazer, estou aguardando.
Abraços
Att
Luiz Maia
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
Ola Fernando,
Tenho o AdventureWorks2008 sim. Ja pode postar sua duvida aqui, estou aguardando.
Abraços
Att
Luiz Maia
Continuo aguardando sua duvida, ok?
Abraços
Att
Luiz Maia
Régis / Fernanda,
o consultor está aguardando sua dúvida para poder solucioná-la.
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