Eu tenho um aplicativo para implantar na produção que usa a segurança do 'sistema de honra'. Ou seja, todos os usuários se conectam ao banco de dados usando uma credencial de usuário/senha SQL e o próprio aplicativo gerencia as permissões. A última parte não me incomoda tanto quanto o fato de que o objeto de conexão contém credenciais incorporadas e pode ser copiado livremente. Estou tentando encontrar uma maneira de limitar as conexões a um conjunto mais limitado de clientes. Posso criar regras de firewall para limitar por IP, claro. Existe alguma maneira de 'pré-qualificar' logins SQL por conta de máquina ou associação de domínio?
Eu executo uma instância do Oracle 11g localmente na minha máquina de desenvolvimento e posso me conectar à instância local diretamente via SqlPlus:
c:\>sqlplus ace
SQL*Plus: Release 11.2.0.2.0 Production on Mon Mar 11 11:50:20 2013
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Enter password:
Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - Beta
SQL> select count(*) from my_table ;
COUNT(*)
----------
5297
Mas não consigo me conectar a ele através do ouvinte:
c:\>sqlplus -L "user/pw@(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))"
SQL*Plus: Release 11.2.0.2.0 Production on Mon Mar 11 11:52:40 2013
Copyright (c) 1982, 2010, Oracle. All rights reserved.
ERROR:
ORA-12514: TNS:listener does not currently know of service requested in connect
descriptor
SP2-0751: Unable to connect to Oracle. Exiting SQL*Plus
Da mesma forma, se eu me conectar via SqlDeveloper, recebo um erro (embora ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
).
Esta instância está estável e funcionando bem por um ano ou mais até hoje, uma segunda-feira de manhã. Nossa TI corporativa às vezes envia novas políticas e atualizações no fim de semana, então presumo que algo mudou, mas não consegui descobrir o quê.
Já reiniciei o serviço e o listener várias vezes, o log do listener não dá nenhuma pista.
O ouvinte parece bem:
c:\>lsnrctl status
LSNRCTL for 32-bit Windows: Version 11.2.0.2.0 - Beta on 11-MAR-2013 11:55:33
Copyright (c) 1991, 2010, Oracle. All rights reserved.
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1)))
STATUS of the LISTENER
------------------------
Alias LISTENER
Version TNSLSNR for 32-bit Windows: Version 11.2.0.2.0 - Beta
Start Date 11-MAR-2013 11:17:30
Uptime 0 days 0 hr. 38 min. 3 sec
Trace Level off
Security ON: Local OS Authentication
SNMP OFF
Default Service XE
Listener Parameter File C:\oraclexe\app\oracle\product\11.2.0\server\network\admin\listener.ora
Listener Log File C:\oraclexe\app\oracle\diag\tnslsnr\FBC305BB46560\listener\alert\log.xml
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\\.\pipe\EXTPROC1ipc)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=machine.domain.com)(PORT=1521)))
Services Summary...
Service "CLRExtProc" has 1 instance(s).
Instance "CLRExtProc", status UNKNOWN, has 1 handler(s) for this service...
Service "PLSExtProc" has 1 instance(s).
Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
The command completed successfully
A porta 1521 parece estar ok:
c:\>netstat -an -O | find /i "1521"
TCP 0.0.0.0:1521 0.0.0.0:0 LISTENING 4368
TCP 169.243.90.109:55307 159.185.207.100:1521 ESTABLISHED 12416
TCP [::]:1521 [::]:0 LISTENING 4368
(PID 4368 é o processo TNSLSNR.exe.)
Além disso, posso tnsping
para o serviço XE:
c:\>tnsping xe
TNS Ping Utility for 32-bit Windows: Version 11.2.0.2.0 - Beta on 11-MAR-2013 12:27:47
Copyright (c) 1997, 2010, Oracle. All rights reserved.
Used parameter files:
C:\oraclexe\app\oracle\product\11.2.0\server\network\admin\sqlnet.ora
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = machine.domain.com)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XE)))
OK (210 msec)
O listenerr.ora
arquivo:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = C:\oraclexe\app\oracle\product\11.2.0\server)
(PROGRAM = extproc)
)
(SID_DESC =
(SID_NAME = CLRExtProc)
(ORACLE_HOME = C:\oraclexe\app\oracle\product\11.2.0\server)
(PROGRAM = extproc)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
(ADDRESS = (PROTOCOL = TCP)(HOST = machine.domain.com)(PORT = 1521))
)
)
DEFAULT_SERVICE_LISTENER = (XE)
Além disso, e não tenho ideia se está relacionado, não consigo acessar o apex https://127.0.0.1:8080/apex
(mesmo que as permissões para isso pareçam boas).
Então, onde mais eu deveria estar procurando?
Atualize com as informações solicitadas:
SQL> show parameter service_names
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
service_names string XE
SQL> show parameter local_listener
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
local_listener string
Update2 : como @miracle173 aponta corretamente, o ouvinte não estava bem. Com o parâmetro 'local_listener' atualizado agora mostra informações extras:
Listening Endpoints Summary...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\\.\pipe\EXTPROC1ipc)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=machine.domain.com)(PORT=1521)))
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521)))
Services Summary...
Service "CLRExtProc" has 1 instance(s).
Instance "CLRExtProc", status UNKNOWN, has 1 handler(s) for this service...
Service "PLSExtProc" has 1 instance(s).
Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service...
Service "XEXDB" has 1 instance(s).
Instance "xe", status READY, has 1 handler(s) for this service...
Service "xe" has 1 instance(s).
Instance "xe", status READY, has 1 handler(s) for this service...
The command completed successfully
Existem situações que exigem uma consulta muito grande juntando várias tabelas com instruções sub select nelas para produzir os resultados desejados.
Minha pergunta é: devemos considerar o uso de várias consultas menores e trazer as operações lógicas para a camada de aplicativo consultando o banco de dados em mais de uma chamada ou é melhor tê-las todas de uma vez?
Por exemplo, considere a seguinte consulta:
SELECT *
FROM `users`
WHERE `user_id` IN (SELECT f2.`friend_user_id`
FROM `friends` AS f1
INNER JOIN `friends` AS f2
ON f1.`friend_user_id` = f2.`user_id`
WHERE f2.`is_page` = 0
AND f1.`user_id` = "%1$d"
AND f2.`friend_user_id` != "%1$d"
AND f2.`friend_user_id` NOT IN (SELECT `friend_user_id`
FROM `friends`
WHERE `user_id` = "%1$d"))
AND `user_id` NOT IN (SELECT `user_id`
FROM `friend_requests`
WHERE `friend_user_id` = "%1$d")
AND `user_image` IS NOT NULL
ORDER BY RAND()
LIMIT %2$d
Qual é a melhor maneira de fazê-lo?
Estou no processo de teste e preenchimento de uma tabela específica que aproveita o SEQUENCE
objeto. Neste processo, estou testando o preenchimento da tabela com dezenas de milhares de linhas de inserção (já que não estou familiarizado com como programar isso). O problema que estou vendo com essa tabela específica é que quando inicio outro teste de população, o SEQUENCE
valor não volta para o primeiro número que eu quero (que é 1).
Quando desejo reexecutar um novo teste, excluo a tabela em questão e executo o seguinte:
DROP SEQUENCE foo.fee;
GO
DROP SCHEMA foo;
GO
Quando quero executar novamente o teste, executo os seguintes comandos SCHEMA
& SEQUENCE
, que são acionados na ordem abaixo:
CREATE SCHEMA foo;
GO
CREATE SEQUENCE foo.fee
START WITH 1
INCREMENT BY 1
NO CYCLE
NO CACHE;
GO
Eu então crio a tabela:
CREATE TABLE foo.sample_table_with_data
(order_number bigint PRIMARY KEY NOT NULL,
sample_column_one nvarchar(max) NULL,
sample_column_two nvarchar(max) NULL,
sample_column_three nvarchar(max) NULL)
GO
Uma vez concluído, executo o seguinte comando de inserção 50.000 vezes:
INSERT INTO [foo].[sample_table_with_data]
(
[order_number],
[sample_column_one],
[sample_column_two],
[sample_column_three]
)
VALUES
(
NEXT VALUE FOR foo.fee,
'Blah',
'Blah Blah',
'Blah Blah Blah'
)
Agora não há absolutamente nenhum problema com os dados entrando na tabela. O desafio que estou encontrando é que, quando eu excluo a tabela, elimino o esquema e a sequência e, em seguida, recrio a tabela, a sequência e o esquema a SEQUENCE
partir do último número na encarnação anterior do banco de dados e não redefinir para um.
Por exemplo, se o último número na sequência for 634.534, o próximo número de sequência na nova tabela será 634.535.
Depois de excluir a tabela e descartar o esquema e a sequência, executo o seguinte para verificar a remoção da sequência e do esquema:
SELECT * FROM INFORMATION_SCHEMA.SCHEMATA
GO
SELECT * FROM sys.sequences
GO
Estou perplexo por que isso está acontecendo. Existe outro comando que estou perdendo aqui que me ajudaria a localizar exatamente o que está acontecendo aqui?
Devo observar que esta tabela pertence a um banco de dados com 7 outras tabelas, todas executando o SEQUENCE
comando corretamente.
Esta é uma instalação do SQL 2012 SP1 Enterprise Edition.
Dada esta pergunta no reddit, limpei a consulta para apontar onde estava o problema na consulta. Eu uso vírgula primeiro e WHERE 1=1
para facilitar a modificação de consultas, então minhas consultas geralmente terminam assim:
SELECT
C.CompanyName
,O.ShippedDate
,OD.UnitPrice
,P.ProductName
FROM
Customers as C
INNER JOIN Orders as O ON C.CustomerID = O.CustomerID
INNER JOIN [Order Details] as OD ON O.OrderID = OD.OrderID
INNER JOIN Products as P ON P.ProductID = OD.ProductID
Where 1=1
-- AND O.ShippedDate Between '4/1/2008' And '4/30/2008'
And P.productname = 'TOFU'
Order By C.CompanyName
Alguém basicamente disse que 1=1 geralmente é preguiçoso e ruim para o desempenho .
Dado que não quero "otimizar prematuramente" - quero seguir boas práticas. Já examinei os planos de consulta antes, mas geralmente apenas para descobrir quais índices posso adicionar (ou ajustar) para tornar minhas consultas mais rápidas.
A questão então realmente... faz Where 1=1
com que coisas ruins aconteçam? E se sim, como posso saber?
Edição secundária: Eu sempre 'assumi' também que isso 1=1
seria otimizado ou, na pior das hipóteses, seria insignificante. Nunca é demais questionar um mantra, como "Goto's are Evil" ou "Premature Optimization..." ou outros fatos presumidos. Não tinha certeza se 1=1 AND
afetaria realisticamente os planos de consulta ou não. E nas subconsultas? CTE's? Procedimentos?
Não sou de otimizar, a menos que seja necessário ... mas se estiver fazendo algo realmente "ruim", gostaria de minimizar os efeitos ou alterar quando aplicável.
Temos um usuário que está saindo e preciso conhecer cada objeto de banco de dados que ele possui. Existe uma consulta que fornecerá essas informações?
Estamos ficando sem espaço. Qual é a maneira segura de limpar o log de erros?
Na última versão do meu aplicativo, adicionei um comando que diz para esperar quando algo chegar na fila do Service Broker:
WAITFOR (RECEIVE CONVERT(int, message_body) AS Message FROM MyQueue)
Os DBAs me disseram que, desde a adição, os tamanhos de toras dispararam. Isso pode estar correto? Ou devo procurar em outro lugar?
No MS SQL Server 2008 R2, preciso ter um usuário que possa criar, restaurar, DBCC CHECKDB e depois descartar bancos de dados. Mas ele não deve poder acessar ou excluir bancos de dados especificados no servidor (motivos de segurança). Essa configuração é possível?
Como posso mover uma chave primária em cluster para um novo grupo de arquivos? Já encontrei um possível "algoritmo" mas é terrivelmente ineficiente:
- Eliminar indexados não clusterizados (exige que sejam reordenados e reconstruídos)
- Eliminar índice clusterizado (requer que toda a tabela seja reordenada)
- Crie uma nova restrição de chave primária (grande operação de classificação)
- Crie todos os índices não clusterizados (classificação e gravação necessárias)
Existe uma maneira mais eficiente? Isso é terrivelmente ineficiente e levará muito tempo, pois a tabela tem 50 GB de tamanho em um servidor fraco.
Não existe uma maneira de pular tudo isso e apenas fazer uma reconstrução em um novo grupo de arquivos? Isso não exigiria nenhuma classificação de dados.