Kashiash's Blog

o programowaniu inaczej : jak zrobić i się nie narobić

Archive for Czerwiec 2010

Zmniejszanie wielkości pliku LOG na SQL

Posted by kashiash w dniu 10 czerwca, 2010

Ostatnio mielismy problem z brakiem miejsca na pliki LOG w ms sql. Baza która miala log file ponad 20 GB skutecznie odmawiala zmniejszenia sie poleceniem shrink z SQL Managera
na słynnej stronie Pinala znalazłem zestaw magicznych zaklęć:

GO
ALTER DATABASE [nazwa bazy] SET RECOVERY SIMPLE WITH NO_WAIT
DBCC SHRINKFILE(nazwa bazy_log, 1)
ALTER DATABASE [nazwa bazy] SET RECOVERY FULL WITH NO_WAIT
GO

w nazwa bazy_log nalezy wpisac logical name pliku logowania

efekty widac po wykonaniu komendy

select * from sys.database_files

Posted in Uncategorized | 3 Komentarze »

Lekcja 2 tabele słownikowe

Posted by kashiash w dniu 6 czerwca, 2010

Delikatnie rozbudujemy dotychczasowa aplikacje. Dodam 3 tabele słownikowe poniewaz aplikacja zbudowana podczas lekcji pierwszej jest zrobiona nieco wbrew sztuce ;).

You Tube zmusza mnie do max 10 minutowych filmików dlatego dzisiaj 3 kawałki:

Posted in kurs clariona | Leave a Comment »

Różnica wydajności zapytań SQL

Posted by kashiash w dniu 6 czerwca, 2010

Na stronie Pinala pojawiło sie ciekawe porównanie czasu wykonania zapytań sql które daja ten sam efekt tylko nieco inaczej są utworzone:

USE AdventureWorks
GO
-- use of =
SELECT *
FROM HumanResources.Employee E
WHERE E.EmployeeID = ( SELECT EA.EmployeeID
FROM HumanResources.EmployeeAddress EA
WHERE EA.EmployeeID = E.EmployeeID)
GO
-- use of in
SELECT *
FROM HumanResources.Employee E
WHERE E.EmployeeID IN ( SELECT EA.EmployeeID
FROM HumanResources.EmployeeAddress EA
WHERE EA.EmployeeID = E.EmployeeID)
GO
-- use of exists
SELECT *
FROM HumanResources.Employee E
WHERE EXISTS ( SELECT EA.EmployeeID
FROM HumanResources.EmployeeAddress EA
WHERE EA.EmployeeID = E.EmployeeID)
GO
-- Use of Join
SELECT *
FROM HumanResources.Employee E
INNER JOIN HumanResources.EmployeeAddress EA ON E.EmployeeID =EA.EmployeeID
GO

link do oryginalnego artykułu na Journey to SQL Authority with Pinal Dave

Posted in SQL | Leave a Comment »

Postać normalna bazy danych

Posted by kashiash w dniu 5 czerwca, 2010

W internecie można znaleźć informacje na temat postaci normalnych w wielu miejscach. Ja znalazłem w formie plakatu. Ważne jest to, że postacie normalne powinny być stosowane ale nie bezmyślnie i bezwzględnie. Niekiedy delikatne odstępstwo sie przydaje. Reguły niestety nie mam … robię to intuicyjnie, po prostu jak normalizacja ci bardzo przeszkadza w pisaniu programu to zrób mały wyjątek. Jak projektujesz bazę projektuj bez wyjątków. Łatwiej jest baze zdenormalizować niż normalizować

Arkusz o normalizacji: rettigNormalizationPoster

Ściąga z SQL SQLServerCheatSheet

Struktura tabel technicznych SQL’a 2008: SQL-SERVER-2008-System-Views-Poster

Posted in Dobre praktyki, SQL | Leave a Comment »

Lekcja 1. Mała aplikacyjka w clarionie

Posted by kashiash w dniu 5 czerwca, 2010

Poniżej krótki filmik jak zrobić prosta palikacje w clarionie

O kilku drobiazgach zapomniałem wiec pokazuje jak poprawic co nieco:

Posted in kurs clariona | Leave a Comment »

Mały filmik o clarionie na YouTube

Posted by kashiash w dniu 4 czerwca, 2010

popełniłem,  zmieściłem. Popełniać zamierzam dalej …

Posted in kurs clariona | 3 Komentarze »

20 najwolniejszych (najdłużej wykonujących się) zapytań SQL

Posted by kashiash w dniu 2 czerwca, 2010

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT TOP 20
CAST(total_elapsed_time / 1000000.0 AS DECIMAL(28, 2)) #A
AS [Total Elapsed Duration (s)]
, execution_count
, SUBSTRING (qt.text,(qs.statement_start_offset/2) + 1, #B
((CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE
qs.statement_end_offset
END - qs.statement_start_offset)/2) + 1) AS [Individual Query]
, qt.text AS [Parent Query]
, DB_NAME(qt.dbid) AS DatabaseName
, qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
INNER JOIN sys.dm_exec_cached_plans as cp
on qs.plan_handle=cp.plan_handle
ORDER BY total_elapsed_time DESC

Posted in SQL | Leave a Comment »

Jak wykryć LOCK w MS SQL Serwer

Posted by kashiash w dniu 2 czerwca, 2010

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

PRINT GETDATE()
EXEC master.dbo.dba_BlockTracer
IF @@ROWCOUNT > 0
BEGIN
SELECT GETDATE() AS TIME
EXEC master.dbo.dba_WhatSQLIsRunning
END
WAITFOR DELAY '00:00:15'
GO 500

potrzebujemy do tego 3 funkcje:

create PROC [dbo].[dba_BlockTracer]
AS

BEGIN

SET TRANSACTION ISOLATION LEVEL READ
UNCOMMITTED

IF EXISTS(SELECT 1 FROM sys.sysprocesses WHERE blocked != 0)
BEGIN

SELECT distinct t1.spid AS [Root blocking spids]
, t1.[loginame] AS [Owner]
, dbo.dba_GetSQLForSpid(t1.spid) AS [SQLText]
, t1.[cpu]
, t1.[physical_io]
, DatabaseName = DB_NAME(t1.[dbid])
, t1.[program_name]
, t1.[hostname]
, t1.[status]
, t1.[cmd]
, t1.[blocked]
, t1.[ecid]
FROM sys.sysprocesses t1, sys.sysprocesses t2
WHERE t1.spid = t2.blocked
AND t1.ecid = t2.ecid
AND t1.blocked = 0
ORDER BY t1.spid, t1.ecid

SELECT t2.spid AS [Blocked spid]
, t2.blocked AS [Blocked By]
, t2.[loginame] AS [Owner]
, dbo.dba_GetSQLForSpid(t2.spid) AS [SQLText]
, t2.[cpu]
, t2.[physical_io]
, DatabaseName = DB_NAME(t2.[dbid])
, t2.[program_name]
, t2.[hostname]
, t2.[status]
, t2.[cmd]
, t2.ecid
FROM sys.sysprocesses t1, sys.sysprocesses t2
WHERE t1.spid = t2.blocked
AND t1.ecid = t2.ecid
ORDER BY t2.blocked, t2.spid, t2.ecid
END

ELSE
PRINT 'No processes blocked.'

END

CREATE PROC [dbo].[dba_WhatSQLIsExecuting]
AS

BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

SELECT [Spid] = session_Id
, ecid
, [Database] = DB_NAME(sp.dbid)
, [User] = nt_username
, [Status] = er.status
, [Wait] = wait_type
, [Individual Query] = SUBSTRING (qt.text,
er.statement_start_offset/2,
(CASE WHEN er.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE er.statement_end_offset END -
er.statement_start_offset)/2)
,[Parent Query] = qt.text
, Program = program_name
, Hostname
, nt_domain
, start_time
FROM sys.dm_exec_requests er
INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle)as qt
WHERE session_Id > 50
AND session_Id NOT IN (@@SPID)
ORDER BY 1, 2
END

CREATE Function [dbo].[dba_GetSQLForSpid]
(
@spid SMALLINT
)
RETURNS NVARCHAR(4000)

/*-------------------------------------------------

Purpose: Returns the SQL text for a given spid.

---------------------------------------------------

Parameters: @spid - SQL Server process ID.
Returns: @SqlText - SQL text for a given spid.
Revision History:
01/12/2006 Ian_Stirk@yahoo.com Initial version
Example Usage:
SELECT dbo.dba_GetSQLForSpid(51)
SELECT dbo.dba_GetSQLForSpid(spid) AS [SQL text]
, * FROM sys.sysprocesses WITH (NOLOCK)

--------------------------------------------------*/

BEGIN
DECLARE @SqlHandle BINARY(20)
DECLARE @SqlText NVARCHAR(4000)
-- Get sql_handle for the given spid.
SELECT @SqlHandle = sql_handle
FROM sys.sysprocesses WITH (nolock) WHERE
spid = @spid
-- Get the SQL text for the given sql_handle.
SELECT @SqlText = [text] FROM
sys.dm_exec_sql_text(@SqlHandle)
RETURN @SqlText

END

Posted in SQL | Leave a Comment »

Dobre nawyki programisty – funkcje

Posted by kashiash w dniu 1 czerwca, 2010

1. Nadmiar argumentów
Funkcje powinny mieć jak najmniej argumentów, najlepiej wcale. W przypadku clariona jest to o tyle możliwe że argumentami funkcji mogą być dane z bieżącego rekordu które dostępne są w całym wątku dla wszystkich procedur. Jeśli argumentów jest wiecej niz 3 warto pomyśleć o stworzeniu obiektu który ma kilka cech i jako parametr przekazywać taki obiekt.
2. Argumenty Wejściowo-Wyjściowe przekazywane zwrotnie przez wskaźnik w clarionie
Nigdy ich nie lubiłem, nie były dla mnie intuicyjne i dość ciężko analizuje się taki kod – jeśli funkcja ma zwracać wiele wyników ..niech zwraca obiekt lub typ złożony (dla nie lubiących OOP)
3. Stare/martwe funkcje
Jeśli funkcja nie jest używana powinna być usunięta z systemu. Podobnie jeśli jest backupem po jej modyfikacji

Posted in Clarion, Dobre praktyki | Otagowane: , , , | Leave a Comment »