Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

CLR i MS SQL Adam Pelikant.

Podobne prezentacje


Prezentacja na temat: "CLR i MS SQL Adam Pelikant."— Zapis prezentacji:

1 CLR i MS SQL Adam Pelikant

2 Assemblies i funkcje using System; public class wynik {
[Microsoft.SqlServer.Server.SqlFunction] public static double reszta(double? a, int b) double wyn = (double)a % b; return wyn; } } Assemblies i funkcje DROP FUNCTION reszta GO DROP ASSEMBLY funkcja CREATE ASSEMBLY [funkcja] AUTHORIZATION [dbo] FROM 'C:\hurtownia_ap\funkcja\funkcja\bin\Debug\funkcja.dll' WITH PERMISSION_SET = SAFE CREATE FUNCTION int) RETURNS float AS EXTERNAL NAME funkcja.wynik.reszta

3 Tworzenie Funkcji składnia
CREATE FUNCTION [<schema name>.]<function name> ( [ name> [AS] [<schema name>.]<scalar data type> [ = <default value>] [ ,...n ] ] ) RETURNS {<scalar type>|TABLE [(<Table Definition>)]} [ WITH [ENCRYPTION]|[SCHEMABINDING]| [ RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT ] | [EXECUTE AS { CALLER|SELF|OWNER|<'user name'>} ] ] [AS] { EXTERNAL NAME <<i>external method</i>> | BEGIN [<function statements>] {RETURN <type as defined in RETURNS clause>|RETURN (<SELECT statement>)} END }[;]

4 Assemblies i funkcje SQL Server data type CLR data type (SQL Server)
CLR data type (.NET Framework) bigint SqlInt64 Int64, Nullable<Int64> binary SqlBytes, SqlBinary Byte[] bit SqlBoolean Boolean, Nullable<Boolean> char None cursor date SqlDateTime DateTime, Nullable<DateTime> datetime datetime2 DATETIMEOFFSET DateTimeOffset, Nullable<DateTimeOffset> decimal SqlDecimal Decimal, Nullable<Decimal> float SqlDouble Double, Nullable<Double> image int SqlInt32 Int32, Nullable<Int32> money SqlMoney nchar SqlChars, SqlString String, Char[] ntext

5 Assemblies i funkcje SQL Server data type CLR data type (SQL Server)
CLR data type (.NET Framework) numeric SqlDecimal Decimal, Nullable<Decimal> nvarchar(1), nchar(1) SqlChars, SqlString Char, String, Char[], Nullable<char> real SqlSingle Single, Nullable<Single> rowversion None Byte[] smallint SqlInt16 Int16, Nullable<Int16> smallmoney SqlMoney sql_variant Object table text time TimeSpan TimeSpan, Nullable<TimeSpan> timestamp tinyint SqlByte Byte, Nullable<Byte> uniqueidentifier SqlGuid Guid, Nullable<Guid> varbinary SqlBytes, SqlBinary varbinary(1), binary(1) byte, Byte[], Nullable<byte> varchar xml SqlXml

6 Assemblies i funkcje SQL Server data type CLR data type (SQL Server)
CLR data type (.NET Framework) geography SqlGeography is defined in Microsoft.SqlServer.Types.dll, which is installed with SQL Server and can be downloaded from the SQL Server 2008 feature pack. None geometry SqlGeometry is defined in Microsoft.SqlServer.Types.dll, which is installed with SQL Server and can be downloaded from the SQL Server 2008 feature pack. hierarchyid SqlHierarchyId is defined in Microsoft.SqlServer.Types.dll, which is installed with SQL Server and can be downloaded from the SQL Server 2008 feature pack. nvarchar SQLChars is a better match for data transfer and access, and SQLString is a better match for performing String operations. String, Char[] User-defined type(UDT) The same class that is bound to the user-defined type in the same assembly or a dependent assembly.

7 Assemblies i procedura
using System; public class wynik { [Microsoft.SqlServer.Server.SqlFunction] public static double reszta(double? a, int b) double wyn = (double)a % b; return wyn; } [Microsoft.SqlServer.Server.SqlProcedure] public static void resztap(double? a, int b, out double wyn) wyn = (double)a % b;

8 Assemblies i procedura
CREATE Procedure float OUTPUT) AS EXTERNAL NAME funkcja.wynik.resztap

9 Assemblies i funkcja tabelaryczna
using System; using System.Data.Sql; using Microsoft.SqlServer.Server; using System.Collections; using System.Data.SqlTypes; using System.Diagnostics; public class wynik { [Microsoft.SqlServer.Server.SqlFunction] public static double reszta(double? a, int b) { double wyn = (double)a % b; return wyn; } [Microsoft.SqlServer.Server.SqlProcedure] public static void resztap(double? a, int b, out double wyn) { wyn = (double)a % b; }

10 Assemblies i funkcja tabelaryczna
[SqlFunction(FillRowMethodName = "FillRow")] public static IEnumerable InitMethod(String logname) { return new EventLog(logname).Entries; } public static void FillRow(Object obj, out SqlDateTime timeWritten, out SqlChars message, out SqlChars category, out long instanceId) EventLogEntry eventLogEntry = (EventLogEntry)obj; timeWritten = new SqlDateTime(eventLogEntry.TimeWritten); message = new SqlChars(eventLogEntry.Message); category = new SqlChars(eventLogEntry.Category); instanceId = eventLogEntry.InstanceId; } } Niedostateczne uprawnienia SELECT TOP 100 * FROM dbo.ReadEventLog(N'Security') as T

11 Assemblies i funkcja tabelaryczna
CREATE ASSEMBLY funkcja FROM 'C:\hurtownia_ap\funkcja\funkcja\bin\Debug\funkcja.dll' WITH PERMISSION_SET = EXTERNAL_ACCESS --Lub = UNSAFE GO CREATE FUNCTION nvarchar(100)) RETURNS TABLE (logTime datetime,Message nvarchar(4000),Category nvarchar(4000),InstanceId bigint) AS EXTERNAL NAME funkcja.wynik.InitMethod ALTER ASSEMBLY funkcja WITH PERMISSION_SET = UNSAFE Niedostateczne uprawnienia SELECT TOP 100 * FROM dbo.ReadEventLog(N'Security') as T

12 Assemblies i funkcja tabelaryczna
use master -- Replace SQL_Server_logon with your SQL Server user credentials. GRANT EXTERNAL ACCESS ASSEMBLY TO [SQL_Server_logon] -- Modify the following line to specify a different database. ALTER DATABASE master SET TRUSTWORTHY ON Podniesienie niedostatecznych uprawnień SELECT TOP 100 * FROM dbo.ReadEventLog(N'Application') as T --FROM dbo.ReadEventLog(N'System') as T --FROM dbo.ReadEventLog(N'Security') as T --FROM dbo.ReadEventLog(N'Internet Explorer') as T logTime Message Category InstanceId :05:46.000 Using 'xpstar.dll' version ' ' to execute extended stored procedure 'xp_instance_regread'. This is an informational message only; no user action is required. Server :05:48.000 A new instance of the full-text filter daemon host process has been successfully started. :05:49.000 Usługa została uruchomiona pomyślnie. %1

13 Assemblies i procedura odwołująca się do bazy
sing System; using Microsoft.SqlServer.Server; using System.Collections; using System.Data; using System.Data.Sql; using System.Data.SqlTypes; using System.Data.SqlClient; using System.Diagnostics; public class wynik { .... [Microsoft.SqlServer.Server.SqlProcedure] public static void wiersze(String tabela, out SqlInt32 ile) ile=0; SqlConnection conn = new SqlConnection("context connection=true"); conn.Open(); SqlCommand zap = new SqlCommand("SELECT count(*) FROM "+ tabela, conn); SqlDataReader zapReader = zap.ExecuteReader(); while (zapReader.Read()) ile = zapReader.GetInt32(0); } } }

14 Assemblies i procedura odwołująca się do bazy
DROP ASSEMBLY funkcja GO CREATE ASSEMBLY [funkcja] AUTHORIZATION [dbo] FROM 'C:\hurtownia_ap\funkcja\funkcja\bin\Debug\funkcja.dll' WITH PERMISSION_SET = SAFE CREATE PROCEDURE int OUTPUT) AS EXTERNAL NAME funkcja.wynik.wiersze int EXEC wiersze OUTPUT

15 Assemblies i funkcja zwracająca tabelę odwołująca się do bazy
using System; using Microsoft.SqlServer.Server; using System.Collections; using System.Data; using System.Data.Sql; using System.Data.SqlTypes; using System.Data.SqlClient; using System.Diagnostics; public class wynik ..... private class ZapResult { public SqlInt32 idosoby; public SqlString nazwisko; public ZapResult(SqlInt32 IdOsoby, SqlString Nazwisko) { idosoby = IdOsoby; nazwisko = Nazwisko; } }

16 Assemblies i funkcja zwracająca tabelę odwołująca się do bazy
[SqlFunction(DataAccess = DataAccessKind.Read, FillRowMethodName = "Pobierz")] public static IEnumerable wysocy(double mini) { ArrayList resultCollection = new ArrayList(); SqlConnection conn = new SqlConnection("context connection=true"); conn.Open(); SqlCommand zap = new SqlCommand("SELECT IdOsoby, Nazwisko FROM Osoby WHERE Wzrost>" + mini, conn); //String.Format(CultureInfo.GetCultureInfo("en-US"), "{0,0}", mini), conn); //min.ToString(CultureInfo.InvariantCulture.NumberFormat),conn); SqlDataReader zapReader = zap.ExecuteReader(); while (zapReader.Read()) resultCollection.Add(new ZapResult(zapReader.GetSqlInt32(0), zapReader.GetSqlString(1))); } return resultCollection; }

17 Assemblies i funkcja zwracająca tabelę odwołująca się do bazy
public static void Pobierz( object zapResultObj, out SqlInt32 idosoby, out SqlString nazwisko) { ZapResult zapResult = (ZapResult)zapResultObj; idosoby = zapResult.idosoby; nazwisko = zapResult.nazwisko; }

18 Assemblies i funkcja zwracająca tabelę odwołująca się do bazy
DROP FUNCTION wysocyf GO DROP ASSEMBLY funkcja CREATE ASSEMBLY [funkcja] AUTHORIZATION [dbo] FROM 'C:\hurtownia_ap\funkcja\funkcja\bin\Debug\funkcja.dll' WITH PERMISSION_SET = SAFE CREATE FUNCTION float) RETURNS TABLE ( kto int, Nazwisko nvarchar(4000) ) AS EXTERNAL NAME funkcja.wynik.wysocy

19 Pomocnicza tabela dla Triggera CLR oraz to co na końcu
CREATE TABLE TAudit (Id int IDENTITY PRIMARY KEY, Nazwa varchar(15)) CREATE ASSEMBLY [trig] AUTHORIZATION [dbo] FROM 'C:\hurtownia\triggerCLR\triggerCLR\bin\Debug\triggerCLR.dll' WITH PERMISSION_SET = SAFE CREATE TRIGGER DzialyAudit ON Dzialy FOR INSERT, UPDATE, DELETE AS EXTERNAL NAME trig.CLRTriggers.Sprawdz

20 Klasa C# dla triggera na tabeli Dzialy
using System; using System.Data; using System.Data.Sql; using Microsoft.SqlServer.Server; using System.Data.SqlClient; using System.Data.SqlTypes; public class CLRTriggers { [SqlTrigger(Name Target = "Dzialy", Event = "FOR INSERT, UPDATE, DELETE")] public static void Sprawdz() string Nazwa; SqlCommand polecenie; SqlTriggerContext kontekst = SqlContext.TriggerContext; SqlPipe pipe = SqlContext.Pipe; SqlDataReader reader;

21 Klasa C# dla triggera na tabeli Dzialy
switch (kontekst.TriggerAction) { case TriggerAction.Insert: // Uzyskaj połączenie używane przez trigger using (SqlConnection conn = new connection=true")) conn.Open(); polecenie = new * FROM INSERTED;", conn); reader = polecenie.ExecuteReader(); reader.Read(); Nazwa = (string)reader[1]; reader.Close(); polecenie = new TAudit VALUES ('" + Nazwa conn); pipe.Send(polecenie.CommandText); polecenie.ExecuteNonQuery(); pipe.Send("Wstawiles: " + Nazwa); } break;

22 Klasa C# dla triggera na tabeli Dzialy
case TriggerAction.Update: // Uzyskaj połączenie używane przez trigger using (SqlConnection conn = new connection=true")) { conn.Open(); polecenie = new * FROM INSERTED;", conn); reader = polecenie.ExecuteReader(); if (reader.HasRows) { while (reader.Read()) Nazwa = (string)reader[1]; '" + Nazwa for (int columnNumber = 0; columnNumber < kontekst.ColumnCount; columnNumber++) { pipe.Send("Zmodyfikowano " + reader.GetName(columnNumber) + "? " + kontekst.IsUpdatedColumn(columnNumber).ToString() ); } } } reader.Close(); } break;

23 Klasa C# dla triggera na tabeli Dzialy
case TriggerAction.Delete: using (SqlConnection connection = new connection=true")) { connection.Open(); polecenie = new * FROM DELETED;", connection); reader = polecenie.ExecuteReader(); if (reader.HasRows) wiersze:"); while (reader.Read()) { + reader.GetString(1) } reader.Close(); //Alternatywnie aby wysłać tabelaryczny wynik możemy zastosować //pipe.ExecuteAndSend(command); } else { pipe.Send("Nie zmieniono żadnych wierszy"); } break; } }}

24 Skutek działania triggera
INSERT TAudit VALUES ('dodany'); Wstawiles: dodany (1 row(s) affected) INSERT TAudit VALUES (‘Nowy'); Wstawiles: Nowy INSERT INTO Dzialy Values('dodany') INSERT INTO Dzialy Values('Nowy') zmieniłeś: 'NOWY' Zmodyfikowano IdDzialu? False Zmodyfikowano Nazwa? True zmieniłeś: 'DODANY' (2 row(s) affected) UPDATE Dzialy SET Nazwa=UPPER(Nazwa) WHERE IdDzialu>10 DELETE FROM Dzialy WHERE IdDzialu>10 Usunąłeś wiersze: 'DODANY' 'NOWY' (2 row(s) affected)

25 W tej samej przestrzeni nazw możemy stworzyć kolejną klasę, tym razem dla triggera na bazie danych
public static void DDLTrigger() { SqlTriggerContext kontekst = SqlContext.TriggerContext; switch (kontekst.TriggerAction) case TriggerAction.DropTable: SqlContext.Pipe.Send("Tabela jest kasowana! Dane z EventData:"); SqlContext.Pipe.Send(kontekst.EventData.Value); break; default: SqlContext.Pipe.Send("Inna akcja DDL! Dane z EventData:"); }

26 Tworzenie assembly i triggerów
DROP TRIGGER DzialyAudit GO DROP TRIGGER AuditDDL ON DATABASE DROP ASSEMBLY [trig] CREATE ASSEMBLY [trig] AUTHORIZATION [dbo] FROM 'C:\hurtownia_ap\trigerCLR\trigerCLR\bin\Debug\trigerCLR.dll' WITH PERMISSION_SET = SAFE go CREATE TRIGGER DzialyAudit ON Dzialy FOR INSERT, UPDATE, DELETE AS EXTERNAL NAME trig.CLRTriggers.Sprawdz CREATE TRIGGER AuditDDL ON DATABASE FOR DDL_DATABASE_LEVEL_EVENTS EXTERNAL NAME trig.CLRTriggers.DDLTrigger

27 Działanie Triggera CLR dla DDL
CREATE TABLE TT (Id int PRIMARY KEY) (1 row(s) affected) Inna akcja DDL! Dane z EventData: <EVENT_INSTANCE><EventType>CREATE_TABLE</EventType><PostTime> T19:56:54.507</PostTime><SPID>52</SPID><ServerName>PC22431</ServerName><LoginName>sa</LoginName><UserName>dbo</UserName><DatabaseName>test</DatabaseName><SchemaName>dbo</SchemaName><ObjectName>TT</ObjectName><ObjectType>TABLE</ObjectType><TSQLCommand><SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" /><CommandText>CREATE TABLE TT (Id int PRIMARY KEY)</CommandText></TSQLCommand></EVENT_INSTANCE>

28 Działanie Triggera CLR dla DDL
ALTER TABLE TT ADD Opis varchar(11) (1 row(s) affected) Inna akcja DDL! Dane z EventData: <EVENT_INSTANCE><EventType>ALTER_TABLE</EventType><PostTime> T19:59:52.537</PostTime><SPID>52</SPID><ServerName>PC22431</ServerName><LoginName>sa</LoginName><UserName>dbo</UserName><DatabaseName>test</DatabaseName><SchemaName>dbo</SchemaName><ObjectName>TT</ObjectName><ObjectType>TABLE</ObjectType><AlterTableActionList><Create><Columns><Name>Opis</Name></Columns></Create></AlterTableActionList><TSQLCommand><SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" /><CommandText>ALTER TABLE TT ADD Opis varchar(11)</CommandText></TSQLCommand></EVENT_INSTANCE>

29 Działanie Triggera CLR dla DDL
DROP TABLE TT (1 row(s) affected) Tabela jest kasowana! Dane z EventData: <EVENT_INSTANCE><EventType>DROP_TABLE</EventType><PostTime> T20:00:22.177</PostTime><SPID>52</SPID><ServerName>PC22431</ServerName><LoginName>sa</LoginName><UserName>dbo</UserName><DatabaseName>test</DatabaseName><SchemaName>dbo</SchemaName><ObjectName>TT</ObjectName><ObjectType>TABLE</ObjectType><TSQLCommand><SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" /><CommandText>DROP TABLE TT </CommandText></TSQLCommand></EVENT_INSTANCE>

30 Działanie Triggera CLR dla DDL
CREATE LOGIN nowy WITH PASSWORD = 'kajak'; Tutaj trigger nie zadziała ponieważ to jest zdarzenie z poziomu ALL SERVER

31 Typy danych użytkownika CLR
using System; using System.Data; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; using System.Text; [Serializable] [Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native, IsByteOrdered = true, ValidationMethodName = "SprawdzPunkt")] public struct Punkt : INullable { private bool is_Null; private Int32 _x; private Int32 _y; public bool IsNull get {return (is_Null);} }

32 Typy danych użytkownika CLR
public static Punkt Null { get { Punkt pt = new Punkt(); pt.is_Null = true; return pt; } } public override string ToString() if (this.IsNull) return "NULL"; else StringBuilder builder = new StringBuilder(); builder.Append(_x); builder.Append(","); builder.Append(_y); return builder.ToString(); }

33 Typy danych użytkownika CLR
[SqlMethod(OnNullCall = false)] public static Punkt Parse(SqlString s) { if (s.IsNull) return Null; Punkt pt = new Punkt(); string[] xy = s.Value.Split(",".ToCharArray()); pt.X = Int32.Parse(xy[0]); pt.Y = Int32.Parse(xy[1]); if (!pt.SprawdzPunkt()) throw new ArgumentException("Invalid XY coordinate values."); return pt; }

34 Typy danych użytkownika CLR
// współrzędne X i Y są ustawiane jako właściwościtypu. public Int32 X { get { return this._x; } set { Int32 temp = _x; _x = value; if (!SprawdzPunkt()) _x = temp; throw new ArgumentException("Zła współrzędna X."); } } } public Int32 Y { return this._y; } Int32 temp = _y; _y = value; _y = temp; Typy danych użytkownika CLR

35 Typy danych użytkownika CLR
// metoda walidująca współrzędne X Y private bool SprawdzPunkt() { if ((_x >= 0) && (_y >= 0)) { return true; } else {return false;} } // Odległość od 0,0. [SqlMethod(OnNullCall = false)] public Double Odleglosc() { return OdlegloscOdXY(0, 0); } // Odległość od wskazanego punktu public Double OdlegloscOd(Punkt pFrom) { return OdlegloscOdXY(pFrom.X, pFrom.Y); } // Odległość od wskazanego punktu. public Double OdlegloscOdXY(Int32 iX, Int32 iY) return Math.Sqrt(Math.Pow(iX - _x, 2.0) + Math.Pow(iY - _y, 2.0)); } } Typy danych użytkownika CLR

36 Typy danych użytkownika CLR po stronie TSQL
DROP Type Punkt GO DROP ASSEMBLY [Punkt_a] CREATE ASSEMBLY [Punkt_a] AUTHORIZATION [dbo] FROM 'C:\hurtownia_ap\udt\udt\bin\Debug\udt.dll' WITH PERMISSION_SET = SAFE CREATE TYPE dbo.Punkt EXTERNAL NAME Punkt_a.Punkt; Typy danych użytkownika CLR po stronie TSQL DROP TABLE Punkty GO CREATE TABLE dbo. Punkty (ID int IDENTITY(1,1) PRIMARY KEY, PunktyXY Punkt) INSERT INTO Punkty VALUES (CONVERT(Punkt, '3,4')); INSERT INTO Punkty VALUES (CONVERT(Punkt, '1,5')); INSERT INTO Punkty VALUES (CAST ('1,99' AS Punkt));

37 Typy danych użytkownika CLR po stronie TSQL
ID PunktyXY 1 0x 2 0x 3 0x (3 row(s) affected) 1 3,4 2 1,5 3 1,99 ID SELECT ID, PunktyXY FROM Punkty GO SELECT ID, PunktyXY.ToString() AS PunktyXY FROM Punkty; SELECT ID, CAST(PunktyXY AS varchar) SELECT ID, CONVERT(varchar, PunktyXY)

38 Typy danych użytkownika CLR po stronie TSQL
PunktXY 1,5 (1 row(s) affected) ID PunktyXY 1 3,4 2 1,5 3 1,99 (3 row(s) affected) Punkt; = (SELECT PunktyXY FROM Punkty WHERE ID = 2); AS PunktXY; GO SELECT ID, PunktyXY.ToString() AS PunktyXY FROM Punkty WHERE PunktyXY > CONVERT(Punkt, '2,2'); WHERE PunktyXY.X < PunktyXY.Y;

39 Typy danych użytkownika CLR po stronie TSQL
SELECT ID, PunktyXY.X AS PunktX, PunktyXY.Y AS PunktY, PunktyXY.Odleglosc() AS OdlegloścOdPoczatku FROM Punkty; go SELECT ID, PunktyXY.ToString() AS Pkt, PunktyXY.OdlegloscOd(CONVERT(Punkt, '1,99')) AS OdlegloscOdPunktu ID PunktX PunktY OdlegloścOdPoczatku , , (3 row(s) affected) ID Pkt OdlegloscOdPunktu 1 3,4 95, 2 1,5 94 3 1,99 0

40 Typy danych użytkownika CLR po stronie TSQL
UPDATE Punkty SET PunktyXY = CAST('1,88' AS Punkt) WHERE ID = 3 GO  SELECT ID, PunktyXY.X AS PunktX, PunktyXY.Y AS PunktY, PunktyXY.Odleglosc() AS OdlegloscOdZero FROM Punkty; GO SET PunktyXY.Y = 99 Typy danych użytkownika CLR po stronie TSQL ID PunktX PunktY OdlegloscOdZero , , ,

41 Typy danych użytkownika CLR po stronie TSQL
UPDATE Punkty SET PunktyXY = '4,5' WHERE PunktyXY = '3,4'; GO  SELECT ID, PunktyXY.X AS PunktX, PunktyXY.Y AS PunktY, PunktyXY.Odleglosc() AS OdlegloscOdZero FROM Punkty; GO ID PunktX PunktY OdlegloscOdZero , , , (3 row(s) affected)

42 Typy danych użytkownika CLR po stronie TSQL
UPDATE Punkty SET PunktyXY.X = 5, PunktyXY.Y = 99 WHERE ID = 3 GO  /*SELECT ID, PunktyXY.X AS PunktX, PunktyXY.Y AS PunktY, PunktyXY.Odleglosc() AS OdlegloscOdZero FROM Punkty;*/ GO SET PunktyXY.SetXY(5, 99) WHERE ID = 3 FROM Punkty; */ Typy danych użytkownika CLR po stronie TSQL Msg 264, Level 16, State 1, Line 1 The column name 'PunktyXY' is specified more than once in the SET clause. A column cannot be assigned more than one value in the same SET clause. Modify the SET clause to make sure that a column is updated only once. If the SET clause updates columns of a view, then the column name 'PunktyXY' may appear twice in the view definition. Msg 6506, Level 16, State 10, Line 3 Could not find method 'SetXY' for type 'Punkt' in assembly 'udt'

43 Pusty

44 Skośność i kurtoza dobre
using System; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; [Serializable] [SqlUserDefinedAggregate( Format.Native, IsInvariantToDuplicates = false, IsInvariantToNulls = true, IsInvariantToOrder = true, IsNullIfEmpty = false)] public struct Skew { private double rx; // running sum of current values (x) private double rx2; // running sum of squared current values (x^2) private double r2x; // running sum of doubled current values (2x) private double rx3; // running sum of current values raised to power 3 (x^3) private double r3x2; // running sum of tripled squared current values (3x^2) private double r3x; // running sum of tripled current values (3x) private Int64 rn; // running count of rows

45 Skośność i kurtoza dobre
public void Init() { rx = 0; rx2 = 0; r2x = 0; rx3 = 0; r3x2 = 0; r3x = 0; rn = 0; } public void Accumulate(double? inpVal) { if (inpVal.IsNull) { return; } rx = rx + inpVal.Value; rx2 = rx2 + Math.Pow(inpVal.Value, 2); r2x = r2x + 2 * inpVal.Value; rx3 = rx3 + Math.Pow(inpVal.Value, 3); r3x2 = r3x2 + 3 * Math.Pow(inpVal.Value, 2); r3x = r3x + 3 * inpVal.Value; rn = rn + 1; }

46 Skośność i kurtoza dobre
public void Merge(Skew Group) { this.rx = this.rx + Group.rx; this.rx2 = this.rx2 + Group.rx2; this.r2x = this.r2x + Group.r2x; this.rx3 = this.rx3 + Group.rx3; this.r3x2 = this.r3x2 + Group.r3x2; this.r3x = this.r3x + Group.r3x; this.rn = this.rn + Group.rn; }

47 Skośność i kurtoza dobre
public double? Terminate() { if (rn == 0) { return null; } else { double myAvg = (rx / rn); if (rn - 1 == 0 & 2d == 0) { return null; } double myStDev = Math.Pow((rx2 - r2x * myAvg + rn * Math.Pow(myAvg, 2)) / (rn - 1), 1d / 2d); double mySkew = (rx3 - r3x2 * myAvg + r3x * Math.Pow(myAvg, 2) - rn * Math.Pow(myAvg, 3)) / Math.Pow(myStDev, 3) * rn / (rn - 1) / (rn - 2); return (dounle?)mySkew; } } }

48 Skośność i kurtoza dobre
[Serializable] [SqlUserDefinedAggregate( Format.Native, IsInvariantToDuplicates = false, IsInvariantToNulls = true, IsInvariantToOrder = true, IsNullIfEmpty = false)] public struct Kurt { private double rx; // running sum of current values (x) private double rx2; // running sum of squared current values (x^2) private double r2x; // running sum of doubled current values (2x) private double rx4; // running sum of current values raised to power 4 (x^4) private double r4x3; // running sum of quadrupled current values raised to power 3 (4x^3) private double r6x2; // running sum of squared current values multiplied by 6 (6x^2) private double r4x; // running sum of quadrupled current values (4x) private Int64 rn; // running count of rows

49 Skośność i kurtoza dobre
public void Init() { rx = 0; rx2 = 0; r2x = 0; rx4 = 0; r4x3 = 0; r6x2 = 0; r4x = 0; rn = 0; } public void Accumulate(double? inpVal) { if (inpVal.IsNull) { return; } rx = rx + inpVal.Value; rx2 = rx2 + Math.Pow(inpVal.Value, 2); r2x = r2x + 2 * inpVal.Value; rx4 = rx4 + Math.Pow(inpVal.Value, 4); r4x3 = r4x3 + 4 * Math.Pow(inpVal.Value, 3); r6x2 = r6x2 + 6 * Math.Pow(inpVal.Value, 2); r4x = r4x + 4 * inpVal.Value; rn = rn + 1; }

50 Skośność i kurtoza dobre
public void Merge(Kurt Group) { this.rx = this.rx + Group.rx; this.rx2 = this.rx2 + Group.rx2; this.r2x = this.r2x + Group.r2x; this.rx4 = this.rx4 + Group.rx4; this.r4x3 = this.r4x3 + Group.r4x3; this.r6x2 = this.r6x2 + Group.r6x2; this.r4x = this.r4x + Group.r4x; this.rn = this.rn + Group.rn; }

51 Skośność i kurtoza dobre
public SqlDouble Terminate() { if (rn == 0) { return null; } else { double myAvg = (rx / rn); if (rn - 1 == 0 & 2d == 0) { return null; } { double myStDev = Math.Pow((rx2 - r2x * myAvg + rn * Math.Pow(myAvg, 2)) / (rn - 1), 1d / 2d); if (rn - 3 == 0) { return null; } { double myKurt = (rx4 - r4x3 * myAvg + r6x2 * Math.Pow(myAvg, 2) - r4x * Math.Pow(myAvg, 3) + rn * Math.Pow(myAvg, 4)) / Math.Pow(myStDev, 4) * rn * (rn + 1) / (rn - 1) / (rn - 2) / (rn - 3) - 3 * Math.Pow((rn - 1), 2) / (rn - 2) / (rn - 3); return (double?)myKurt; } } } } }

52 Skośność i kurtoza dobre
USE BazaRelacyjna; GO DROP AGGREGATE dbo.Skew go DROP AGGREGATE dbo.Kurt drop assembly DescriptiveStatistics CREATE ASSEMBLY DescriptiveStatistics FROM 'C:\hurtownia_ap\kurtosa\kurtosa\bin\Debug\kurtosa.dll' WITH PERMISSION_SET = SAFE; CREATE AGGREGATE float) RETURNS float EXTERNAL NAME DescriptiveStatistics.Skew; CREATE AGGREGATE float) EXTERNAL NAME DescriptiveStatistics.Kurt;

53 Skośność i kurtoza dobre
SELECT IdDzialu, dbo.Skew(wzrost) AS Skew, dbo.Kurt(Wzrost) AS Kurt FROM Osoby GROUP BY IdDzialu IdDzialu Skew Kurt 1 -1, 2, 2 -0, -5, 3 0, -1, 4 -0, 0, 5 0, 1, 6 -0, -1, 7 -0, -4, 8 1, NULL

54 Pusty

55 Zastosowanie listy do obliczania funkcji statystycznych
using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using System.Collections; using System.Collections.Generic; using Microsoft.SqlServer.Server; using System.Text; [Serializable] [SqlUserDefinedAggregate(Format.UserDefined, IsInvariantToDuplicates = false, IsInvariantToOrder= false, MaxByteSize =8000 , Name="OdchylenieStandardowe")] public struct OdchStd : IBinarySerialize { public List<double> posr; private int licznik; // zmienna zliczająca liczbę wierszy nie mających wartości NULL private double suma; // zmienna przechowująca sumę pól private double temp; // zmienna pomocnicza

56 Zastosowanie listy do obliczania funkcji statystycznych
public void Init() { posr = new List<double>(); licznik = 0; suma = 0; } public void Accumulate(double? value) if (value != null) // wyznaczanie sumy dla pól nie mających wartości NULL licznik++; temp = (double)value; suma = suma + temp; posr.Add(temp);

57 Zastosowanie listy do obliczania funkcji statystycznych
public void Merge(OdchStd Group) { this.suma += Group.suma; this.licznik += Group.licznik; this.temp += Group.temp; // kiedy obliczenia równoległe suma staje się sumą z wszystkich procesów } public double? Terminate() //SqlString if (licznik == 0) return null; else return (double?)(this.temp); //zwrócenie ostatecznej wartości obliczeń } }

58 Zastosowanie listy do obliczania funkcji statystycznych
public void Write(System.IO.BinaryWriter w) { temp = 0; double sr = suma / licznik; foreach (double d in posr) temp = temp + Math.Pow((d- sr),2); } temp = temp / (licznik-1); temp = Math.Pow(temp, 0.5); w.Write(temp); //w.Write(suma); w.Write(licznik); public void Read(System.IO.BinaryReader r) temp = r.ReadDouble(); //suma = r.ReadDouble(); licznik = r.ReadInt32(); } }

59 Zastosowanie listy do obliczania funkcji statystycznych
USE [BazaRelacyjna] GO DROP AGGREGATE ODCHSTD DROP ASSEMBLY [ODCHSTD_a] CREATE ASSEMBLY [ODCHSTD_a] AUTHORIZATION [dbo] FROM 'C:\hurtownia\cowariancja\cowariancja\bin\Debug\cowariancja.dll' WITH PERMISSION_SET = SAFE CREATE AGGREGATE float) RETURNS float EXTERNAL NAME ODCHSTD_a.OdchStd;

60 Zastosowanie listy do obliczania funkcji statystycznych
SELECT Opis, stdev(wzrost), dbo.OdchStd(Wzrost) FROM Dzialy LEFT JOIN osoby ON Dzialy.IdDzialu=Osoby.IdDzialu GROUP BY Opis Opis funkcja Assembly wsp Administracja E-12 Dyrekcja E-12 Gospodarczy E-12 Handlowy E-12 Inny E-12 Nowy NULL Obsługa E-12 Pomocniczy E-12 Techniczny E-13

61 Zastosowanie listy macierzy do obliczania funkcji statystycznych
[Serializable] [SqlUserDefinedAggregate(Format.UserDefined, IsInvariantToDuplicates = false, IsInvariantToOrder = false, MaxByteSize = 8000, Name = "Kowariancja")] public struct Kowariancja : IBinarySerialize { double[] a ; public ArrayList posr; private int licznik; private double sumaX; private double sumaY; private double tempX; private double tempY; private double temp;

62 Zastosowanie listy macierzy do obliczania funkcji statystycznych
public void Init() { a = new double[2]; posr = new ArrayList(a); posr.Clear(); temp = 0; licznik = 0; sumaX = 0; sumaY = 0; }

63 Zastosowanie listy macierzy do obliczania funkcji statystycznych
public void Accumulate(double? valueX, double? valueY) { if (valueX != null && valueY != null) { licznik++; a[0] = (double)valueX; a[1] = (double)valueY; sumaX = sumaX + a[0]; sumaY = sumaY + a[1]; posr.Add(a.Clone()); } } public void Merge(Kowariancja Group) this.sumaX += Group.sumaX; this.sumaY += Group.sumaY; this.licznik += Group.licznik; posr.AddRange(Group.posr); }

64 Zastosowanie listy macierzy do obliczania funkcji statystycznych
public double? Terminate() { if (licznik == 0) { return null; } else { return (double?)(this.temp); //zwrócenie ostatecznej wartości obliczeń } } public void Read(System.IO.BinaryReader r) temp = r.ReadDouble(); licznik = r.ReadInt32();

65 Zastosowanie listy macierzy do obliczania funkcji statystycznych
public void Write(System.IO.BinaryWriter w) { temp = 0; double srX = sumaX / licznik; double srY = sumaY / licznik; foreach (double[] d in posr) tempX = (d[0]- srX); tempY = (d[1] - srY); temp = temp + (tempX * tempY); } temp = temp/ licznik; w.Write(temp); w.Write(licznik);

66 Zastosowanie listy macierzy do obliczania funkcji statystycznych
USE [BazaRelacyjna] GO DROP AGGREGATE COVAR DROP AGGREGATE ODCHSTD DROP ASSEMBLY [ODCHSTD_a] CREATE ASSEMBLY [ODCHSTD_a] AUTHORIZATION [dbo] FROM 'C:\hurtownia\cowariancja\cowariancja\bin\Debug\cowariancja.dll' WITH PERMISSION_SET = SAFE CREATE AGGREGATE float) RETURNS float EXTERNAL NAME ODCHSTD_a.OdchStd; CREATE AGGREGATE float) EXTERNAL NAME ODCHSTD_a.Kowariancja;

67 Zastosowanie listy macierzy do obliczania funkcji statystycznych
Tabela Test A B 1 9 SELECT AVG(A)AS sr, stdevp(a) AS odch, dbo.Covar(A, B) AS covara, (AVG(A * B)- AVG(A)*AVG(B))as Covar FROM Test sr odch covara Covar 5 4 16

68 Zastosowanie listy macierzy do obliczania funkcji statystycznych
SELECT Opis, stdevp(wzrost) AS funOdch2, dbo.OdchStd(Wzrost)AS AssOdch, dbo.Covar(Wzrost, Wzrost)AS AssCoVar , (AVG(WZROST * wzrost)- AVG(wzrost)*AVG(wzrost))/(stdevp(wzrost)*stdevp(wzrost)) as Corr, dbo.Covar(Wzrost, Wzrost)/(stdevp(Wzrost)*stdevp(Wzrost))AS AssCorr FROM Dzialy LEFT JOIN osoby ON Dzialy.IdDzialu=Osoby.IdDzialu GROUP BY Opis Opis funOdch2 AssOdch AssCoVar Corr AssCorr Administracja Dyrekcja Gospodarczy Handlowy Inny Nowy NULL Obsługa Pomocniczy Techniczny


Pobierz ppt "CLR i MS SQL Adam Pelikant."

Podobne prezentacje


Reklamy Google