neljapäev, 26. veebruar 2009

SQL2005 ASP.NET WebService-t kasutava CLR protseduuri tegemine VisualStudio2008-ga

Selline keerulisem juhtum, et käiakse nagu uni peale, et tahetakse saada arvet PDF kujul ka e-postiga aga mul see arve trükk tehtud VisualStudio2008 ReportVieweriga, ehk RDLC fail ASP.NET veebirakenduse küljes ja nüüd tahetakse seda sama asja saada e-posti peale. Aga arveid on sadu ja tuleb ka igale eraldi saata ning kui nüüd hakata veebis ootama, kuni need tuhat arvet valmis tehakse ja minema saadetakse võib asi kätte ära surra. Lahendus selline, et võtab SQL SERVICE BROKERI kasutusele, topib need arve numbrid, mida e-postile saata sinna sisse ja paneb pärast andmebaasi töö (SqlServerAgent job) käima, mis neid arveid teele lähetab




Kõigepealt teeme ASP.NET WebService VisualStudio 2008 -ga


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using Microsoft.Reporting.WebForms;

namespace KampusInvoice
{
///



/// Summary description for Invoice
///

[WebService(Namespace = "http://www.codewiser.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
//[System.Web.Script.Services.ScriptService]
public class Invoice : System.Web.Services.WebService
{
[WebMethod]
public byte[] InvoicePdf(string raportkataloog, int invoice_form, short keel, long arvenr, int arvetyyp, int tenant)
{
//tõmbame arve trüki RDLC reporti bitijadaks
byte[] pdfsisu = null;

try
{
Microsoft.Reporting.WebForms.LocalReport pdfreport = new LocalReport();
// see peab olema just see "TurukampusConnectionString" millega andembaasi pole pöördume
string connString = System.Configuration.ConfigurationManager.ConnectionStrings["TurukampusConnectionString"].ConnectionString.Trim();
//RDLC kasutab ühte GAC-is olevat DLL-i
pdfreport.AddTrustedCodeModuleInCurrentAppDomain("ReportFunctions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=437410073a8b26ba");
//paneme RDLC-le andmed külge
switch (invoice_form)
{
case 1: //TTÜ
{
pdfreport.ReportPath = raportkataloog + "InvoiceTTU.rdlc";
InvoicesPrintTableAdapters.TENANT_NAVISION_DEBT_KUIDO_STableAdapter nta = new InvoicesPrintTableAdapters.TENANT_NAVISION_DEBT_KUIDO_STableAdapter();
InvoicesPrint.TENANT_NAVISION_DEBT_KUIDO_SDataTable ntab = new InvoicesPrint.TENANT_NAVISION_DEBT_KUIDO_SDataTable();
nta.Connection.ConnectionString = connString;
nta.Fill(ntab, tenant, null);
pdfreport.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource("dsAccounts_TENANT_NAVISION_DEBT_KUIDO_S", ntab));
InvoicesPrint.ACCOUNT_PARTICIPATORY_KUIDO_SDataTable apt = new InvoicesPrint.ACCOUNT_PARTICIPATORY_KUIDO_SDataTable();
InvoicesPrintTableAdapters.ACCOUNT_PARTICIPATORY_KUIDO_STableAdapter apad = new InvoicesPrintTableAdapters.ACCOUNT_PARTICIPATORY_KUIDO_STableAdapter();
apad.Connection.ConnectionString = connString;
apad.Fill(apt, arvenr);
pdfreport.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource("dsAccounts_ACCOUNT_PARTICIPATORY_KUIDO_S", apt));

break;
}
default: //turku
{
pdfreport.ReportPath = raportkataloog + "Invoice.rdlc";
break;
}

}


InvoicesPrintTableAdapters.ACCOUNT_DETAILS_PRINT_KUIDO_STableAdapter taprin = new InvoicesPrintTableAdapters.ACCOUNT_DETAILS_PRINT_KUIDO_STableAdapter();
InvoicesPrint.ACCOUNT_DETAILS_PRINT_KUIDO_SDataTable taprintable = new InvoicesPrint.ACCOUNT_DETAILS_PRINT_KUIDO_SDataTable();
taprin.Connection.ConnectionString = connString;
taprin.Fill(taprintable, arvenr, keel);
pdfreport.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource("dsAccounts_ACCOUNT_DETAILS_PRINT_KUIDO_S", taprintable));

InvoicesPrintTableAdapters.LOGOS_KUIDO_STableAdapter lo = new InvoicesPrintTableAdapters.LOGOS_KUIDO_STableAdapter();
InvoicesPrint.LOGOS_KUIDO_SDataTable lotab = new InvoicesPrint.LOGOS_KUIDO_SDataTable();
lo.Connection.ConnectionString = connString;
lo.Fill(lotab, 1); //1 ON ARVE VÄLJATRÜKI LOGO
pdfreport.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource("dsAccounts_LOGOS_KUIDO_S", lotab));
InvoicesPrintTableAdapters.INVOICE_TYPE_BANK_ACCOUNT_STableAdapter ta = new InvoicesPrintTableAdapters.INVOICE_TYPE_BANK_ACCOUNT_STableAdapter();
InvoicesPrint.INVOICE_TYPE_BANK_ACCOUNT_SDataTable tb = new InvoicesPrint.INVOICE_TYPE_BANK_ACCOUNT_SDataTable();
ta.Connection.ConnectionString = connString;
tb.Locale = System.Globalization.CultureInfo.CurrentCulture;
ta.Fill(tb, Convert.ToInt32(arvetyyp));
pdfreport.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource("dsAccounts_INVOICE_TYPE_BANK_ACCOUNT_S", tb));
pdfreport.EnableExternalImages = true;

//teeme selle reporti väljatrüki bitijadaks
Warning[] warnings;
string[] streamids;
string mimeType;
string encoding;
string extension;
pdfsisu = pdfreport.Render("PDF", null, out mimeType, out encoding, out extension, out streamids, out warnings);

}
catch (SystemException ex)
{
throw ex;
}
return pdfsisu;
}
}
}

ja installime IIS-i peale ning kontrollime kas töötab, kontrollime vastavalt URL-lt

http://10.0.40.8:4434/Invoice.asmx

Seejärel teeme uue Visual C# SqlServer projekti, kuhu lisame Reference System.Web.Services. Kui on SQL2005 versioon, siis kompileerib dll-i .NET version 2.0-ga

ja sinna teeb ühe SQL2005 CLR salvestatud protseduuri
public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void ArvePdf(SqlString raportkataloog, SqlInt32 invoice_form, SqlInt16 keel, SqlInt64 arvenr,
SqlInt32 arvetyyp, SqlInt32 tenant, SqlString fail, SqlString WebServiceUrl)
{
try
{
byte[] sisu = null;

// see KampusArve.Invoice ilmub alles siis, kui oled WebService proxy ära teinud ja projekti lisanud
// vahepeal kui midagi ArvePdf-s muudad, tuleb proxy KuidoInvoice.cs projektist ära kustutada ja uuesti lisada
KampusArve.Invoice arve = new KampusArve.Invoice();
arve.Url = (string)WebServiceUrl; // "http://10.0.40.8:4434/Invoice.asmx";
sisu = arve.InvoicePdf((string)raportkataloog, (int)invoice_form, (short)keel, (long)arvenr, (int)arvetyyp, (int)tenant);
arve.Dispose(); //mälu vabaks igaks juhuks
FileInfo fil = new FileInfo((string)fail);
FileStream f = fil.OpenWrite();
f.Write(sisu, 0, sisu.Length);
f.Close();
}
catch (SystemException ex)
{
throw ex;
}

}
};

Nüüd tuleb luua proxy klass selle WebService poole pöördumiseks

wsdl /o:KuidoInvoice.cs /n:KampusArve http://10.0.40.8:4434/Invoice.asmx

KampusArve on see namespace mis luuakse

http://10.0.40.8:4434/Invoice.asmx on olemasolev ASP.NET Webservice, mis sai enne tehtud

localhosti tegemisel kasuta, kui teed lokaalses masinas ja service on 81 pordis
wsdl /o:KuidoInvoice.cs /n:KampusArve http://localhost:81/Invoice.asmx

KuidoInvoice.cs on nüüd see proxy klass mis tehakse

Nüüd tuleb see fail lisada VisualStudio2008s vastavasse VisualC# SqlServer projekti




nüüd teeme nendest kahest failist library

csc /target:library /out:KampusWebService.dll ArvePdf.cs KuidoInvoice.cs

ja teeme ka staatilise serialization assembly, kuna SQL2005 teisiti ei luba

sgen /a:KampusWebService.dll /force

nüüd nagu asjad olemas (KampusWebService.XmlSerializers.dll ja KampusWebService.dll)

NB! Kui midagi muuta ArvePdf.cs- tuleb see proxy KuidoInvoice.cs projektist eemaldada ja uuesti teha WSDL.exe.ga ning teegid samuti uuesti luua.

paneme tehtud library-d SQL2005 sisse, kuna pöördume WebService poole siis ASSEMBLY teeme UNSAFE suvandiga. Failid tuleb ennem kopeerida SQLSERVER-i kõvakettale

VisualStudio2015 võib vaja minna et tuleb luua ka xmlserializers.dll, mis luuakse, kui lisada signeerimsvõti ja serializerdll luuaks sgen.exe käsuga
sgen /force /compiler:/keyfile:c:\Campus\KampusPdfInvoice\KampusPFDInvoice.snk KampusPdfInvoice.dll

Tekkinud
CREATE ASSEMBLY KampusVeeb
FROM 'C:\CAMPUS\KampusVeeb\bin\Debug\KampusVeeb.dll'
WITH PERMISSION_SET = UNSAFE

VisualStudio2008 deploy siin KampusWebService.dll ja KampusWebService.XmlSerializers.dll ei liiguta, tuleb käsitsi teha

CREATE ASSEMBLY KampusWebService FROM 'D:\TEMP\KampusWebService.dll'
WITH PERMISSION_SET = UNSAFE

ja ka serialization assembly, see saab olla SAFE

CREATE ASSEMBLY [KampusWebService.XmlSerializers]
FROM 'D:\TEMP\KampusWebService.XmlSerializers.dll'
WITH PERMISSION_SET = SAFE

Loome ka nüüd protseduuri SQL SERVER-isse

CREATE PROCEDURE dbo.ArvePdf
@raportkataloog NVARCHAR(400),
@invoice_form INT,
@keel SMALLINT,
@arvenr BIGINT,
@arvetyyp INT,
@tenant INT,
@fail NVARCHAR(2000),
@WebServiceUrl NVARCHAR(2000)
AS EXTERNAL NAME KampusWebService.StoredProcedures.ArvePdf


Proovime, kas töötab
--@raportkataloog on see kataloog IIS-i serveri peale, kus põhirakenduse enda RDLC --failid asuvad

EXECUTE [dbo].[ArvePdf]
@raportkataloog='D:\cw-turukampus\Raportid\'
,@invoice_form=1
,@keel=24
,@arvenr=26236
,@arvetyyp=600000
,@tenant=271088
,@fail='G:\temp\kuido.pdf'
,@WebServiceUrl='http://10.0.40.8:4434/Invoice.asmx'

ja tulemusena peaks see fail valmis olema G:\temp\kuido.pdf, mida saab nüüd e-postiga teele panna

Blogged with the Flock Browser

esmaspäev, 23. veebruar 2009

SQL2005 CLR meetodi dünaamiline väljakutsumine teisest CLR meetodist

Kuna kulus kaks päeva teadasaamiseks, kuidas asju teha ei saa nüüd siis nüüd puust ja punaselt

CLR tegemine SQL2005 tuleb teha .NET Framework Versiooniga 2.0 kuna LINQ-i SQL2005 veel ei tunne

Ehk probleem, et teeme ühe ASSEMBLY ja selles sees olevast meetodist on vaja pöörduda teise ASSEMBLY meetodite poole.
SQL2005 lubab välja kutsuda ainult SQLSERVER-i enda sisse laetud ASSEMBLY-sid. Võimalus tegelikult ka mujalt , näiteks GAC-ist aga
võib pista kisama. Need DLL-id mida saab SQL2005 ASSEMBLYKS teha on piiratud ja muid DLL-e saab sisse laadida UNSAFE suvandiga.
Aga näide selline, et
ASSEMBLY TurukampusSqlPdf ja selle sees meetod ArvePdf mis pöördub ASSEMBLY Laad meetodite KasLaeb ja Laeb poole

ASSEMBLY Laad meetodid sellised

public partial class Protseduurid //See peab sellise nimega olema, selle kaudu leitakse ülesse
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void KasLaeb( ref String nimi) //siit loeb ka ref parameetri tagasi
{
string s="Tere ";
nimi = s+nimi;
}

[Microsoft.SqlServer.Server.SqlProcedure]
public static void Laeb()
{
string s = "Tere ";
s += "Kere";
}
}


ASSEMLBLY TurukampusSqlPdf meetod ArvePdf tahab nüüd neid kätte saada


using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Reflection.Emit;
using System.Reflection;
using System.Diagnostics;
using System.IO;


public partial class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void ArvePdf(SqlString raportkataloog, SqlInt32 invoice_form, SqlInt32 keel, SqlInt64 arvenr,
SqlInt32 arvetyyp, SqlInt32 tenant, SqlString fail)
{
try
{

// assembly laadimine tuleb teha täisnimega
Assembly repf = Assembly.Load("Laad, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
Type MyType = repf.GetType("Protseduurid"); //siin on see klassi nimi oluline
if (MyType != null)
{
object MyObj = Activator.CreateInstance(MyType);
//kutsume välja meetodi
MyType.InvokeMember("Laeb", BindingFlags.Default BindingFlags.InvokeMethod, null, null, new object[] { });
//kutsume välja meetodi koos parameetritega
object[] MyParameter = new object[] { "Kuido" };
object tar = new object();
MyType.InvokeMember("KasLaeb", BindingFlags.Default BindingFlags.InvokeMethod, null, tar, MyParameter);
// MyParameter[0].ToString() on nüüd see, mille KasLaeb meetodist parameetrina tagasi loeme

//kirjutame selle bitijadana faili
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] sisu = encoding.GetBytes(tar.GetType().FullName + " " + tar.ToString() + " " + MyParameter[0].ToString());
FileInfo fil = new FileInfo((string)fail);
FileStream f = fil.OpenWrite();
f.Write(sisu, 0, sisu.Length);
f.Close();
}

}
catch (SystemException ex)
{
throw ex;
}

}
}



Blogged with the Flock Browser

pühapäev, 22. veebruar 2009

Kuidas leida ülesse kõik ühte tüüpi elemendid aspx veebilehe pealt

No on vaja ülesse leida kõik usercontrolid või mida iganes aspx veebilehe pealt
Siin üks näide, kuida ülesse leida kõik teatud interface kasutavad usercontrolid antud näites


/// <summary>
/// leiame kõik antud lehel olevad ICVPublishView interfacega olevad asjad ülesse
/// </summary>
/// <returns></returns>
private List<ETISUserControls.Views.ICVPublishView> FindICVPublishViewUserControls()
{
List<ETISUserControls.Views.ICVPublishView> ICVkontrollid = new List<ETISUserControls.Views.ICVPublishView>();
ICVPublishViewUserControl(this.Page.Form, ICVkontrollid); //siin kindlasti tähele panna, et controlid on lehe Form objekti omad
return ICVkontrollid; // siin nimekirjas on nad nüüd kõik olemas
}

Kasutame rekursiivset pöördumist, iga controli seest otsime omakorda edasi

private void ICVPublishViewUserControl(Control kont, List<ETISUserControls.Views.ICVPublishView> ICVkontroll)
{
try
{
if (kont != null) //igaks juhuks, kunagi ei või teada mis aspx veebilehe eventis asja kasutatakse, this.Page.Form võib ka veel null olla
{
foreach (Control ker in kont.Controls)
{
// siin kontollime,kas asi on "õige asi" kasutame C# "as" operandi, kas annab antud tüübiks pöörata
ETISUserControls.Views.ICVPublishView hte = ker as ETISUserControls.Views.ICVPublishView;
if (hte != null) // kui oli õige asi siis lisame nimekirja
{
ICVkontroll.Add(hte); //"as" teeb kohe ka selle õige objekti valmis, lihtsalt kontrolliks piisab ka "is" operandist
}
else //leitud ICVPublishView seest enam ei otsi
{
ICVPublishViewUserControl(ker, ICVkontroll);
}
}
}
}
catch (SystemException ex)
{
this.CustomValidator1.ErrorMessage = ex.Message;
this.CustomValidator1.IsValid = false;
}
}



Kuidas asja kasutada

//paneme asjad nimekirja
List<ETISUserControls.Views.ICVPublishView> kontro = this.FindICVPublishViewUserControls();
//nüüd on meil list leitud objektidega olemas
foreach (ETISUserControls.Views.ICVPublishView ker in kontro)
{
ker.CfPers_CV_row = this.CfPers_CV_row; //rakendame asja
}

Blogged with the Flock Browser

kolmapäev, 18. veebruar 2009

SERVICE BROKERI-s protseduuri käivitamine

Kui paned SERVICE BROKERI tööle ja ei saa aru, mis ta tööle ei lähe siis üle ka kontrolida, kuids sul asi on ülesse ehitatud.
QUEUE PROCEDURE_NAME on asi mis tuleb selgeks teha
Kui vaja, et saadaks sõnumi "saatmise" peale tuleb teha üks QUEUE ja panna serviced sama QUEUEd kasutama

Kui saadad sama serveri piires, siis WITH ENCRYPTION = OFF, muidu ei pruugi töötada

CREATE MESSAGE TYPE [KAMPUS_INVOICE] VALIDATION = WELL_FORMED_XML

CREATE CONTRACT [KAMPUS_SEND_INVOICE_EMAIL]
([KAMPUS_INVOICE] SENT BY INITIATOR)


CREATE QUEUE KAMPUS_INVOICES
WITH ACTIVATION
(
STATUS = ON,
PROCEDURE_NAME = KAMPUS_ARVE_EPOST3,
MAX_QUEUE_READERS = 2,
EXECUTE AS 'DBO' )

CREATE SERVICE KAMPUS_SEND3
ON QUEUE KAMPUS_INVOICES ([KAMPUS_SEND_INVOICE_EMAIL])

CREATE SERVICE KAMPUS_RECEIVE3
ON QUEUE KAMPUS_INVOICES ([KAMPUS_SEND_INVOICE_EMAIL])

ja kui nüüd saata sõnum
DECLARE @StockDialog uniqueidentifier
DECLARE @Message XML
BEGIN DIALOG CONVERSATION @StockDialog
FROM SERVICE KAMPUS_SEND3
TO SERVICE 'KAMPUS_RECEIVE3'
ON CONTRACT KAMPUS_SEND_INVOICE_EMAIL
WITH ENCRYPTION = OFF
SET @Message = CAST('<mess>Add 12 widgets to inventory</mess>' AS XML);
SEND ON CONVERSATION @StockDialog
MESSAGE TYPE KAMPUS_INVOICE (@Message)
SET @Message = CAST('<mess>Remove 4 springs from inventory</mess>' AS XML);
SEND ON CONVERSATION @StockDialog
MESSAGE TYPE KAMPUS_INVOICE (@Message)

END CONVERSATION @StockDialog

siis tõmmatakse protseduur KAMPUS_ARVE_EPOST3 käima

ALTER PROCEDURE [dbo].[KAMPUS_ARVE_EPOST3]
AS
BEGIN
SET NOCOUNT ON
DECLARE @dialog_handle UNIQUEIDENTIFIER, @sonu NVARCHAR(2300), @mb VARBINARY(MAX), @jrk INT, @jrkmax INT, @sub NVARCHAR(400)
DECLARE @tulem TABLE ( jrk INT IDENTITY(1,1) PRIMARY KEY, [STATUS] TINYINT, [SERVICE_NAME] NVARCHAR(512), [conversation_handle] UNIQUEIDENTIFIER, message_body
VARBINARY(MAX) )
;
WAITFOR
(
RECEIVE [status], [SERVICE_NAME], [conversation_handle],message_body
FROM KAMPUS_INVOICES
INTO @tulem
), TIMEOUT 8000
SET @jrk = 1
SET @dialog_handle = (SELECT TOP 1 [conversation_handle] FROM @tulem)
SET @jrkmax=(SELECT MAX(jrk) FROM @tulem)
WHILE @jrk <= @jrkmax
BEGIN
SELECT @sonu = CAST(message_body AS NVARCHAR(2000)) FROM @tulem WHERE jrk = @jrk
IF @sonu IS NOT NULL
BEGIN

SET @sub='KAMPUS_INVOICES_SEND3 '+CAST(CURRENT_TIMESTAMP AS NVARCHAR(25))
EXECUTE [dbo].[SEND_MAIL_KUIDO_I]
@mail_post_from='saatja@email.com'
,@mail_to='saaja@email.com'
,@message_subject=@sub
,@sonum=@sonu
END
SET @jrk=@jrk+1

END

IF @dialog_handle IS NOT NULL
END CONVERSATION @dialog_handle

END
END


Kui on vaja panna "lugemise" peale tööle, ehk tehakse kaks QUEUE
CREATE MESSAGE TYPE [KAMPUS_INVOICE] VALIDATION = WELL_FORMED_XML

CREATE CONTRACT [KAMPUS_SEND_INVOICE_EMAIL]
([KAMPUS_INVOICE] SENT BY INITIATOR)

--TEEME KAKS QUEUED

CREATE QUEUE KAMPUS_INVOICES_SEND

CREATE QUEUE KAMPUS_INVOICES_READ
WITH ACTIVATION
(
STATUS = ON,
PROCEDURE_NAME = KAMPUS_ARVE_EPOST,
MAX_QUEUE_READERS = 2,
EXECUTE AS 'DBO' )

--ja SERVICED on erinevate QUEUE-de peal
CREATE SERVICE KAMPUS_SEND
ON QUEUE KAMPUS_INVOICES_SEND ([KAMPUS_SEND_INVOICE_EMAIL])

CREATE SERVICE KAMPUS_RECEIVE
ON QUEUE KAMPUS_INVOICES_READ ([KAMPUS_SEND_INVOICE_EMAIL])

--kui nüüd saata
DECLARE @StockDialog uniqueidentifier
DECLARE @Message XML
BEGIN DIALOG CONVERSATION @StockDialog
FROM SERVICE KAMPUS_SEND
TO SERVICE 'KAMPUS_RECEIVE'
ON CONTRACT KAMPUS_SEND_INVOICE_EMAIL
WITH ENCRYPTION = OFF
SET @Message = CAST('<mess>Add 12 widgets to inventory</mess>' AS XML);
SEND ON CONVERSATION @StockDialog
MESSAGE TYPE KAMPUS_INVOICE (@Message)
SET @Message = CAST('<mess>Remove 4 springs from inventory</mess>' AS XML);
SEND ON CONVERSATION @StockDialog
MESSAGE TYPE KAMPUS_INVOICE (@Message)

END CONVERSATION @StockDialog

--tõmmatakse protseduur käima KAMPUS_ARVE_EPOST mis loeb ainult KAMPUS_INVOICES_READ QUEUE-st

ALTER PROCEDURE [dbo].[KAMPUS_ARVE_EPOST]
AS
BEGIN
SET NOCOUNT ON
DECLARE @dialog_handle UNIQUEIDENTIFIER, @sonu NVARCHAR(2300), @mb VARBINARY(MAX), @jrk INT, @jrkmax INT, @sub NVARCHAR(50)
DECLARE @tulem TABLE ( jrk INT IDENTITY(1,1) PRIMARY KEY, [STATUS] TINYINT, [SERVICE_NAME] NVARCHAR(512), [conversation_handle] UNIQUEIDENTIFIER, message_body
VARBINARY(MAX) )
;
WAITFOR
(
RECEIVE [status], [SERVICE_NAME], [conversation_handle],message_body
FROM [KAMPUS_INVOICES_READ]
INTO @tulem
), TIMEOUT 8000

SET @jrk = 1
SET @dialog_handle = (SELECT TOP 1 [conversation_handle] FROM @tulem)
SET @jrkmax=(SELECT MAX(jrk) FROM @tulem)
WHILE @jrk <= @jrkmax
BEGIN
SELECT @sonu = CAST(message_body AS NVARCHAR(2000)) FROM @tulem WHERE jrk = @jrk
IF @sonu IS NOT NULL
BEGIN
SET @sub='KAMPUS_INVOICES_READ '+CAST(CURRENT_TIMESTAMP AS NVARCHAR(25))
EXECUTE [dbo].[SEND_MAIL_KUIDO_I]
@mail_post_from='saatja@email.com'
,@mail_to='saaja@email.com'
,@message_subject=@sub
,@sonum=@sonu
END
SET @jrk=@jrk+1

END

IF @dialog_handle IS NOT NULL
END CONVERSATION @dialog_handle

END


salakaval ; peab olema õige koha peal

Blogged with the Flock Browser

reede, 6. veebruar 2009

GridView footeri dünaamiline määramine

// kui paned olemasolevale gridview-le tulpasid juurde
for (int i = 0; i < majasi.Length; i++)
{
//see miskipärast ei tööta
this.GridViewKulud.Columns[i+2].FooterText = String.Format("{0:F2}",Convert.ToDecimal(tulpsummad.FindByText(majasi[i]).Value));
//see töötab
this.GridViewKulud.FooterRow.Cells[i + 2].Text = String.Format("{0:F2}", Convert.ToDecimal(tulpsummad.FindByText(majasi[i]).Value));
}

//olemasolevatele tulpadele töötab aga just vastupidi