set nocount on declare #cur cursor for select name from sys.databases where database_id > 4 order by name open #cur declare @db as nvarchar(100) fetch next from #cur into @db declare @sq as nvarchar(max) while @@fetch_status = 0 begin set @sq = N' USE [' + @db + '] --CREATE USER [user.name] FOR LOGIN [user.name] --EXEC sp_addrolemember N''db_owner'', N''user.name'' --DROP USER [user.name] ' print @sq exec sp_executesql @sq fetch next from #cur into @db end close #cur deallocate #cur
19 October 2010
Crea utente per tutti i db
08 June 2010
SQL SERVER – Merge Operations – Insert, Update, Delete in Single Execution
This blog post is written in response to T-SQL Tuesday hosted by Jorge Segarra(aka SQLChicken).
I have been very active using these Merge operations in my development. However, I have found out from my consultancy work and friends that these amazing operations are not utilized by them most of the time. Here is my attempt to bring the necessity of using the Merge Operation to surface one more time.
MERGE is a new feature that provides an efficient way to do multiple DML operations. In earlier versions of SQL Server, we had to write separate statements to INSERT, UPDATE, or DELETE data based on certain conditions; however, at present, by using the MERGE statement, we can include the logic of such data changes in one statement that even checks when the data is matched and then just update it, and similarly, when the data is unmatched, it is inserted.
One of the most important advantages of MERGE statement is that the entire data are read and processed only once. In earlier versions, three different statements had to be written to process three different activities (INSERT, UPDATE or DELETE); however, by using MERGE statement, all the update activities can be done in one pass of database table.
I have written about these Merge Operations earlier in my blog post over here SQL SERVER – 2008 – Introduction to Merge Statement – One Statement for INSERT, UPDATE, DELETE. I was asked by one of the readers that how do we know that this operator was doing everything in single pass and was not calling this Merge Operator multiple times.
Let us run the same example which I have used earlier; I am listing the same here again for convenience.
--Let’s create Student Details and StudentTotalMarks and inserted some records. USE tempdb GO CREATE TABLE StudentDetails ( StudentID INTEGER PRIMARY KEY, StudentName VARCHAR(15) ) GO INSERT INTO StudentDetails VALUES(1,'SMITH') INSERT INTO StudentDetails VALUES(2,'ALLEN') INSERT INTO StudentDetails VALUES(3,'JONES') INSERT INTO StudentDetails VALUES(4,'MARTIN') INSERT INTO StudentDetails VALUES(5,'JAMES') GO CREATE TABLE StudentTotalMarks ( StudentID INTEGER REFERENCES StudentDetails, StudentMarks INTEGER ) GO INSERT INTO StudentTotalMarks VALUES(1,230) INSERT INTO StudentTotalMarks VALUES(2,255) INSERT INTO StudentTotalMarks VALUES(3,200) GO -- Select from Table SELECT * FROM StudentDetails GO SELECT * FROM StudentTotalMarks GO -- Merge Statement MERGE StudentTotalMarks AS stm USING (SELECT StudentID,StudentName FROM StudentDetails) AS sd ON stm.StudentID = sd.StudentID WHEN MATCHED AND stm.StudentMarks > 250 THEN DELETE WHEN MATCHED THEN UPDATE SET stm.StudentMarks = stm.StudentMarks + 25 WHEN NOT MATCHED THEN INSERT(StudentID,StudentMarks) VALUES(sd.StudentID,25); GO -- Select from Table SELECT * FROM StudentDetails GO SELECT * FROM StudentTotalMarks GO -- Clean up DROP TABLE StudentDetails GO DROP TABLE StudentTotalMarks GO
The Merge Join performs very well and the following result is obtained.
Let us check the execution plan for the merge operator. You can click on following image to enlarge it.
Let us evaluate the execution plan for the Table Merge Operator only.
We can clearly see that the Number of Executions property suggests value 1. Which is quite clear that in a single PASS, the Merge Operation completes the operations of Insert, Update and Delete.
I strongly suggest you all to use this operation, if possible, in your development. I have seen this operation implemented in many data warehousing applications.
Trovato qui.
17 May 2010
Cursore con “where current of”
set nocount on -- CREO TABELLA TEMPORANEA ---------------------------------------------------- drop table #p create table #p ( id int ) insert #p values (10) insert #p values (20) insert #p values (30) insert #p values (40) insert #p values (50) insert #p values (60) insert #p values (70) insert #p values (80) select * from #p -- DICHIARO IL CURSORE -------------------------------------------------------- declare @i int declare #c cursor local for select id from #p open #c fetch next from #c into @i while @@fetch_status = 0 begin set @i = @i + 100 update #p set id = @i where current of #c fetch next from #c into @i end close #c deallocate #c select * from #p
Elimina file più vecchi di n giorni con ricorsione - BosoCleanDir.vbs / Delete old files
- impostare i parametri
- la riga che elimina i file è remmata
HACK:
- ottenere i parametri da commandline.
BosoCleanDir.vbs
' -- 2015-10-31 - aggiunto qualche echo()
Option Explicit
'------------------------------------------------------------------------------
' -- PARAMETRI
const elencoCartelle = "c:\test\1,c:\test\bla bla 2"
const maxGiorni = 30
'------------------------------------------------------------------------------
sub eliminaFile(wPath, oggi)
if trim(wpath) = "" then exit sub
with wscript
.echo
.echo "**** Processing directory: " & wpath
end with
dim wFileSystem, wFolder, wSubFolders, f, file
set wFileSystem = createobject("Scripting.FileSystemObject")
set wFolder = wFileSystem.getfolder(wPath)
' -- ELIMINA TUTTI I FILE PIU' VECCHI DI [maxGiorni] GIORNI
for each file in wFolder.Files
if DateDiff("d", file.DateCreated, oggi) > maxGiorni then
wscript.echo "Deleting " & file.name
' file.delete(true)
end if
next
' -- ELIMINA I FILES NELLE SOTTOCARTELLE
dim subFolder
for each subFolder in wFolder.SubFolders
eliminaFile subFolder, oggi
next
set file = nothing
set wFileSystem = nothing
set wFolder = nothing
Set wSubFolders = nothing
end sub
'------------------------------------------------------------------------------
sub Main()
' -- LOOP SULL'ELENCO DELLE CARTELLE
dim arrFolder
arrFolder = Split(elencoCartelle, ",")
dim oggi
oggi = now
dim riga
riga = string(80, "*")
with wscript
.echo
.echo riga
.echo "* DELETING FILES OLDER THAN " & maxGiorni & " DAYS"
.echo riga
dim cartella
for each cartella in arrFolder
eliminaFile cartella, oggi
next
.echo
.echo "** DONE"
end with
end sub
'------------------------------------------------------------------------------
Main
Versione alternativa, senza output
Questa versione pulisce i log di IIS:
sLogFolder = "c:\inetpub\logs\LogFiles"
iMaxAge = 30 'in days
Set objFSO = CreateObject("Scripting.FileSystemObject")
set colFolder = objFSO.GetFolder(sLogFolder)
For Each colSubfolder in colFolder.SubFolders
Set objFolder = objFSO.GetFolder(colSubfolder.Path)
Set colFiles = objFolder.Files
For Each objFile in colFiles
iFileAge = now-objFile.DateCreated
if iFileAge > (iMaxAge+1) then
objFSO.deletefile objFile, True
end if
Next
Next
Via.
Chiudere la connessione dal DataReader
// C# version
public static IDataReader SelectByRoyalty(int Percentage)
{
SqlDataReader dr=null;
SqlConnection cn=new SqlConnection
("Server=Aron1;Database=pubs;Trusted_Connection=True;");
cn.Open();
try
{
SqlCommand cmd=new SqlCommand("byRoyalty",cn);
cmd.CommandType=CommandType.StoredProcedure;
cmd.Parameters.Add("@Percentage",Percentage);
dr=cmd.ExecuteReader(CommandBehavior.CloseConnection);
}
catch ( Exception Ex )
{
if ( dr!=null )
{
dr.Close();
cn.Close();
}
throw Ex;
}
return (IDataReader)dr;
}
' VB version
Public Shared Function SelectByRoyalty(ByVal Percentage As Integer) As IDataReader
Dim dr As SqlDataReader = Nothing
Dim cn As New SqlConnection("Server=Aron1;Database=pubs;Trusted_Connection=True;")
cn.Open()
Try
Dim cmd As New SqlCommand("byRoyalty", cn)
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.Add("@Percentage", Percentage)
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
Catch Ex As Exception
If dr <> Nothing Then
dr.Close()
cn.Close()
End If
Throw Ex
End Try
Return DirectCast(dr, IDataReader)
End Function
IDataReader dr=Coatings.SelectCoating(CoatingID);
try
{
// Use the DataReader..
}
Finally
{
dr.Close();
}
Cerca opzioni database su un server
-- This script works well in SQL 2000, didn't test in 2005+)
DECLARE @DataBase sysname
DECLARE database_cursor CURSOR FOR
SELECT quotename(name) as Base
FROM master..sysdatabases
WHERE DATABASEPROPERTYEX(name, 'Status') = 'ONLINE' AND
DATABASEPROPERTYEX(name, 'IsAutoShrink') = 1
OPEN database_cursor
FETCH NEXT
FROM database_cursor
INTO @DataBase
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @DataBase
-- EXEC ('ALTER DATABASE ' + @DataBase + ' SET AUTO_SHRINK OFF')
FETCH NEXT
FROM database_cursor
INTO @DataBase
END
CLOSE database_cursor
DEALLOCATE database_cursor
GO Apri UI stampa attendendo esecuzione comando
Dim WshShell, oExec
dim wCmd
' COMANDO DA ESEGUIRE
wCmd = "rundll32 printui.dll,PrintUIEntry /o /n\\nome_macchina\nome_stampante"
' CREA L'OGGETTO SHELL (PER LANCIARE IL COMANDO)
set WshShell = CreateObject("WScript.Shell")
' ESEGUE IL COMANDO
set oExec = WshShell.Exec(wcmd)
' ATTENDE IL TERMINE DELL'ESECUZIONE DEL COMANDO
Do While oExec.Status = 0
WScript.Sleep 100
Loop
' ESECUZIONE TERMINATA!
MsgBox oExec.Status
' SVUOTA OGGETTI (PER "RISPARMIARE" MEMORIA)
set WshShell = nothing
set oExec = nothingConversione di codice html in testo piano
Piccolo e utile frammento di codice che, utilizzando le amate/odiate espressioni regolari, ripulisce dai tag html il testo passato.
Imports System.Text
Imports System.Text.RegularExpressions
Function Html2Text(ByVal html As String) As String
Dim repattern As String = “\<[^\>]*\>“
Dim rexp As New Regex(repattern, RegexOptions.IgnoreCase)
html = rexp.Replace(html, String.Empty)
Return html
End Function
sp_who filtrata
set nocount on drop table #boso create table #boso ( spid nvarchar(max), ecid nvarchar(max), status nvarchar(max), loginame nvarchar(max), hostname nvarchar(max), blk nvarchar(max), dbname nvarchar(max), cmd nvarchar(max), request_id nvarchar(max) ) insert #boso exec sp_who select * from #boso where dbname = 'ITPORTAL_FALCONE' order by status
Accesso ai dati asincrono – Async data access
Namespace DotNetSide.Articles.AsyncDataAccess
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Data.SqlClient
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Public Class Form1
Inherits Form
Public Sub New()
MyBase.New
InitializeComponent
End Sub
Private Sub btnStart_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim myConnection As SqlConnection = New SqlConnection
myConnection.ConnectionString = "Data Source=.\\SQLEXPRESS;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=ProgrammareADONet;async=true"
myConnection.Open
Dim cmd As SqlCommand = myConnection.CreateCommand
cmd.CommandText = "WaitFor Delay '00:00:15' Select @@Version"
cmd.BeginExecuteReader(New AsyncCallback(ProcessResult), cmd)
End Sub
Public Sub ProcessResult(ByVal asyncRes As IAsyncResult)
Dim cmd As SqlCommand = CType(asyncRes.AsyncState,SqlCommand)
cmd.Connection
cmd
Dim DBVersion As String = string.Empty
Dim myReader As SqlDataReader = cmd.EndExecuteReader(asyncRes)
If myReader.Read Then
DBVersion = myReader(0).ToString
lbltextVersion.BeginInvoke(New LabelHnd(Update), DBVersion)
End If
End Sub
Public Sub Update(ByVal text As String)
lbltextVersion.Text = text
End Sub
Public Delegate Sub LabelHnd(ByVal value As String)
End Class
End Namespace
Apri Access da .NET
' Apre una form in un db di AccessForm, passando la WhereCondition
Private Sub ApriAccess()
Try
Console.WriteLine("premi un tasto per aprire access...")
Console.ReadKey()
Dim a As New Access.Application
a.OpenCurrentDatabase("d:\pippo.mdb")
a.DoCmd.OpenForm("Form1", , , " Nome='C' ")
a.Visible = True
Console.WriteLine("premi un tasto per chiudere access...")
Console.ReadKey()
a.CloseCurrentDatabase()
Catch ex As Exception
End Try
a = Nothing
End Sub
Cerca campi orfani fra due tabelle
create procedure sys_CampiOrfani_sp
@tab1 as nvarchar(100),
@tab2 as nvarchar(100)
AS
BEGIN
set nocount on
select c.*, s.name as typeName
into #aaa
from sys.columns c inner join sys.types s on
c.system_type_id = s.system_type_id
where c.object_id = object_id(@tab1)
select c.*, s.name as typeName
into #bbb
from sys.columns c inner join sys.types s on
c.system_type_id = s.system_type_id
where c.object_id = object_id(@tab2)
select @tab1 AS 'Table name', a.name AS 'Nome campo', a.typeName,
a.max_length, a.precision, a.scale
from #aaa a LEFT join #bbb b on
a.name = b.name
where b.name is null
order by
a.name
select @tab2 AS 'Table name', b.name AS 'Nome campo', b.typeName,
b.max_length, b.precision, b.scale
from #aaa a RIGHT join #bbb b on
a.name = b.name
where a.name is null
order by
b.name
END
go
exec sys_CampiOrfani_sp
'MPS_InterventiStorico',
'RichiesteManutenzione_tb'
if object_id('sys_CampiOrfani_sp') is not null
drop procedure sys_CampiOrfani_sp13 May 2010
SQL CSV to Table
ALTER Function [dbo].[Csv2Table_fn] (@CSVList nvarchar(1000)) RETURNS @Table table (id nvarchar(50)) AS BEGIN DECLARE @sep AS nvarchar(1); SET @sep = ',' IF RIGHT(@CSVList, 1) <> @sep SET @CSVList = @CSVList + @sep DECLARE @Pos smallint; SET @Pos = 1 DECLARE @OldPos smallint; SET @OldPos = 1 WHILE @Pos < LEN(@CSVList) BEGIN SET @Pos = CHARINDEX(@sep, @CSVList, @OldPos) INSERT @Table SELECT LTRIM(RTRIM(SUBSTRING(@CSVList, @OldPos, @Pos - @OldPos))) SET @OldPos = @Pos + 1 END RETURN END GO -- ESEMPIO: DECLARE @S AS NVARCHAR(100) SET @S = 'ROSSO, VERDE,BLU, BOSO' SELECT * FROM CSVToTable_fn(@S)
VERSIONE CON SEPARATORE PARAMETRICO:
CREATE FUNCTION [dbo].[Csv2Table_fn] ( @CSVList nvarchar(MAX) , @sep nvarchar(1) = ',' ) RETURNS @Table table (id nvarchar(50)) AS BEGIN IF RIGHT(@CSVList, 1) <> @sep SET @CSVList = @CSVList + @sep DECLARE @Pos smallint; SET @Pos = 1 DECLARE @OldPos smallint; SET @OldPos = 1 WHILE @Pos < LEN(@CSVList) BEGIN SET @Pos = CHARINDEX(@sep, @CSVList, @OldPos) INSERT @Table SELECT LTRIM(RTRIM(SUBSTRING(@CSVList, @OldPos, @Pos - @OldPos))) SET @OldPos = @Pos + 1 END RETURN END GOUTILIZZATO PER SPLITTARE UNA STRINGA:
DECLARE @split table (Id nvarchar(50), Posizione int)
INSERT @split (Id, Posizione)
SELECT Id, ROW_NUMBER() OVER (ORDER BY GETDATE()) - 1
FROM GVSYS..Csv2Table_fn('38023454.XZQ.QWE.00029466.0768.txt', '.')
SELECT *
FROM @split s
-- RISULTATO:
Id Posizione
---------------------
38023454 0
XZQ 1
QWE 2
00029466 3
0768 4
txt 5
Trovato qui.
COPY/XCOPY from network: restartable mode
/Z Copies networked files in restartable mode.And this simple, built-in tool turned out to be the thing I needed. It was, every time, able to restart the download properly, and after a few times, it downloaded the file correctly.
A couple of tips:
- If you interrupt the command with Ctrl-C, it will delete the portion copied so far and you'll have to restart the copy from the beginning. If you must interrupt a copy, simply terminate the network connection (it will die with an error, but leave the copied-so-far file) or close the window where the command is running.
- When you restart it and it asks if you want to overwrite, you must answer "yes". You can also use the /Y flag.
Trovato qui.
05 May 2010
Rinumera record con una sola update
IF OBJECT_ID('tempdb..#tmp') IS NOT NULL
DROP TABLE #tmp
SELECT IdArgomento, IdPagina, OrdineVis
INTO #tmp
FROM PagineArgomenti_tb
WHERE IdArgomento = 171
ORDER BY OrdineVis
DECLARE @Newpos smallint
SELECT @Newpos = 0
UPDATE #tmp
SET @Newpos = OrdineVis = @Newpos + 10
UPDATE p
SET p.OrdineVis = t.OrdineVis
FROM PagineArgomenti_tb p
INNER JOIN #tmp t
ON p.IdArgomento = t.IdArgomento
AND p.IdPagina = t.IdPagina
Oppure, con la funzione ROW_NUMBER()
IF OBJECT_ID('tempdb..#tmp') IS NOT NULL
DROP TABLE #tmp
SELECT IdArgomento, IdPagina, ROW_NUMBER() OVER (ORDER BY OrdineVis) AS OrdineVis
INTO #tmp
FROM PagineArgomenti_tb
WHERE IdArgomento = 171
UPDATE p
SET p.OrdineVis = t.OrdineVis
FROM PagineArgomenti_tb p
INNER JOIN #tmp t
ON p.IdArgomento = t.IdArgomento
AND p.IdPagina = t.IdPagina
L'ORDER BY è dentro la OVER().
Se voglio un progressivo e basta, si può fare ROW_NUMBER() OVER (ORDER BY GETDATE())
29 April 2010
The 10/20/30 Rule of PowerPoint
- Ten slides. Ten is the optimal number of slides in a PowerPoint presentation because a normal human being cannot comprehend more than ten concepts in a meeting—and venture capitalists are very normal. (The only difference between you and venture capitalist is that he is getting paid to gamble with someone else’s money). If you must use more than ten slides to explain your business, you probably don’t have a business. The ten topics that a venture capitalist cares about are:
- Problem
- Your solution
- Business model
- Underlying magic/technology
- Marketing and sales
- Competition
- Team
- Projections and milestones
- Status and timeline
- Summary and call to action
-
- Twenty minutes. You should give your ten slides in twenty minutes. Sure, you have an hour time slot, but you’re using a Windows laptop, so it will take forty minutes to make it work with the projector. Even if setup goes perfectly, people will arrive late and have to leave early. In a perfect world, you give your pitch in twenty minutes, and you have forty minutes left for discussion.
- Thirty-point font. The majority of the presentations that I see have text in a ten point font. As much text as possible is jammed into the slide, and then the presenter reads it. However, as soon as the audience figures out that you’re reading the text, it reads ahead of you because it can read faster than you can speak. The result is that you and the audience are out of synch.The reason people use a small font is twofold: first, that they don’t know their material well enough; second, they think that more text is more convincing. Total bozosity. Force yourself to use no font smaller than thirty points. I guarantee it will make your presentations better because it requires you to find the most salient points and to know how to explain them well. If “thirty points,” is too dogmatic, the I offer you an algorithm: find out the age of the oldest person in your audience and divide it by two. That’s your optimal font size.
26 April 2010
#1016 Trasformazione di Web.Config in Visual Studio 2010
di Marco De Sanctis
http://www.aspitalia.com/script/1016/Sharp1016-Trasformazione-Web.Config-Visual-Studio-2010.aspx
Tra le novità di Visual Studio 2010, una estremamente utile riguarda la possibilità di gestire differenti file di configurazione grazie a Web Config Transformation, che consiste in un semplice linguaggio di scripting tramite il quale indicare come il file Web.Config che utilizziamo nel nostro ambiente di sviluppo debba essere rielaborato prima di essere distribuito.
Supponiamo ad esempio che la nostra applicazione si interfacci al database Northwind tramite questa stringa di connessione che, come possiamo notare, punta ad un database locale utilizzando l'autenticazione di Windows.
<add name="Northwind"
connectionString="server=.;database=Northwind;Integrated Security=SSPI"/>
Tipicamente abbiamo diverse impostazioni di questo tipo, che oltre al database possono riguardare log, posta elettronica, pagine di errore personalizzate, e che ogni volta che effettuiamo un deployment completo siamo costretti a modificare manualmente.
Con Visual Studio 2010, se espandiamo il file Web.Config su Solution Explorer possiamo notare la presenza di ulteriori due file, che contengono le trasformazioni necessarie per le configurazioni Debug e Release.
Ovviamente, se la nostra solution dovesse possedere ulteriori configurazioni, ad esempio Test o Staging, è possibile creare le relative trasformazioni selezionando la voce Add Config Transforms dal menu contestuale che si apre su Web.Config.
Il contenuto di questi file è simile ad un normale Web.Config, a parte la dichiarazione di un particolare namespace xml che abilita l'utilizzo dei tag di trasformazione.
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> ... </configuration>
Supponiamo allora di voler modificare il Web.Config generato in Release in modo che la stringa di connessione Northwind sia quella relativa al database di produzione. Ciò che possiamo fare è indicarne la trasformazione all'interno del file Web.Release.Config come segue:
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<connectionStrings>
<add name="Northwind"
connectionString="server=productionServer;database=Northwind;username=test;password=pwd"
xdt:Locator="Match(name)" xdt:Transform="Replace"/>
</connectionStrings>
</configuration>
I due nuovi tag xdt:Locator e xdt:Transform consentono di specificare come la trasformazione deve avvenire, e in particolare:
- xdt:Locator rappresenta la modalità secondo cui deve essere individuata la stringa di connessione da trasformare, nel nostro caso con Match(name) abbiamo indicato che la ricerca deve essere effettuata in base al valore dell'attributo name;
- xdt:Transform rappresenta invece la trasformazione vera e propria, nel nostro caso abbiamo specificato Replace per indicare che la stringa di connessione Northwind sul file originale dovrà essere sostituita con quella corrente.
L'elenco completo di tutte le funzionalità di questi due tag è disponibile a questo indirizzo:
http://msdn.microsoft.com/en-us/library/dd465326.aspx
Se a questo punto generiamo il pacchetto di installazione (Project -> Build Deployment Package) o effettuiamo la pubblicazione della nostra Web Application (Build -> Publish Web Application) in configurazione Release, al Web.Config originale saranno automaticamente applicate le trasformazioni specificate.
Se pensiamo al fatto che, grazie alle nuove modalità di pubblicazione di Visual Studio 2010, è possibile fare in modo che avvenga in automatico anche l'upload del pacchetto di installazione sul server in hosting e la registrazione in IIS, ci possiamo subito rendere conto di come sia potente questo nuovo strumento, grazie al quale possiamo a tutti gli effetti gestire diversi scenari di deployment con pochissimi click del mouse.
14 April 2010
Inserire testo random in Word / Lorem Ipsum generator
You need to write the same function in Word as;
=rand()
On pressing enter, you will see the auto-fill paragraph.
Another place holding text filler which has been widely used in web designing and other prototypes is;
Lorem ipsum dolor sit amet, consectetur adipisicing elit……
For filling Word document with this placeholder filler, you need write it as
=lorem()
Note:
- Testato in Word 2007
- Alle funzioni si può passare un parametro numerico (la lunghezza del testo??).
Trovato qui.
31 March 2010
How To: Use Regular Expressions to Constrain Input in ASP.NET
J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Andy Wigley
Microsoft Corporation
May 2005
Applies To
- ASP.NET version 1.0
- ASP.NET version 1.1
- ASP.NET version 2.0
Summary
This How To shows how you can use regular expressions within ASP.NET applications to constrain untrusted input. Regular expressions are a good way to validate text fields such as names, addresses, phone numbers, and other user information. You can use them to constrain input, apply formatting rules, and check lengths. To validate input captured with server controls, you can use the RegularExpressionValidator control. To validate other forms of input, such as query strings, cookies, and HTML control input, you can use the System.Text.RegularExpressions.Regex class.This How To shows how you can use regular expressions within ASP.NET applications to constrain untrusted input.
Contents
ObjectivesOverview
Using a RegularExpressionValidator Control
Using the Regex Class
Common Regular Expressions
Additional Resources
Objectives
- Use regular expressions to constrain input, apply format rules, and check lengths.
- Use the ASP.NET RegularExpressionValidator control to constrain and validate input.
- Use the Regex class to constrain and validate input.
- Learn common regular expressions that can be used to constrain input.
Overview
If you make unfounded assumptions about the type, length, format, or range of input, your application is unlikely to be robust. Input validation can become a security issue if an attacker discovers that you have made unfounded assumptions. The attacker can then supply carefully crafted input that compromises your application by attempting SQL injection, cross-site scripting, and other injection attacks. To avoid such vulnerability, you should validate text fields (such as names, addresses, tax identification numbers, and so on) and use regular expressions to do the following:- Constrain the acceptable range of input characters.
- Apply formatting rules. For example, pattern-based fields, such as tax identification numbers, ZIP Codes, or postal codes, require specific patterns of input characters.
- Check lengths.
Using a RegularExpressionValidator Control
If you capture input by using server controls, you can use the RegularExpressionValidator control to validate that input. You can use regular expressions to restrict the range of valid characters, to strip unwanted characters, and to perform length and format checks. You can constrain the input format by defining patterns that the input must match.To validate a server control's input using a RegularExpressionValidator
- Add a RegularExpressionValidator control to your page.
- Set the ControlToValidate property to indicate which control to validate.
- Set the ValidationExpression property to an appropriate regular expression.
- Set the ErrorMessage property to define the message to display if the validation fails.
<%@ language="C#" %>
<form id="form1" runat="server">
<asp:TextBox ID="txtName" runat="server"/>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" />
<asp:RegularExpressionValidator ID="regexpName" runat="server"
ErrorMessage="This expression does not validate."
ControlToValidate="txtName"
ValidationExpression="^[a-zA-Z'.\s]{1,40}$" />
</form>
The regular expression used in the preceding code example constrains an input name field to alphabetic characters (lowercase and uppercase), space characters, the single quotation mark (or apostrophe) for names such as O'Dell, and the period or dot character. In addition, the field length is constrained to 40 characters.
Using ^ and $
Enclosing the expression in the caret (^) and dollar sign ($)markers ensures that the expression consists of the desired content and nothing else. A ^matches the position at the beginning of the input string and a $ matches the position at the end of the input string. If you omit these markers, an attacker could affix malicious input to the beginning or end of valid content and bypass your filter.Using the Regex Class
If you are not using server controls (which means you cannot use the validation controls) or if you need to validate input from sources other than form fields, such as query string parameters or cookies, you can use the Regex class within the System.Text.RegularExpressions namespace.To use the Regex class
- Add a using statement to reference the System.Text.RegularExpressions namespace.
- Call the IsMatch method of the Regex class, as shown in the following example.
// Instance method: Regex reg = new Regex(@"^[a-zA-Z'.]{1,40}$"); Response.Write(reg.IsMatch(txtName.Text)); // Static method: if (!Regex.IsMatch(txtName.Text, @"^[a-zA-Z'.]{1,40}$")) { // Name does not match schema }
The following example shows how to use a regular expression to validate a name input through a regular client-side HTML control.
<%@ Page Language="C#" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<form id="form1" method="post" action="HtmlControls.aspx">
Name:
<input name="txtName" type="text" />
<input name="submitBtn" type="Submit" value="Submit"/>
</form>
</body>
</html>
<script runat="server">
void Page_Load(object sender, EventArgs e)
{
if (Request.RequestType == "POST")
{
string name = Request.Form["txtName"];
if (name.Length > 0)
{
if (System.Text.RegularExpressions.Regex.IsMatch(name,
"^[a-zA-Z'.]{1,40}$"))
Response.Write("Valid name");
else
Response.Write("Invalid name");
}
}
}
</script>
Use Regular Expression Comments
Regular expressions are much easier to understand if you use the following syntax and comment each component of the expression by using a number sign (#). To enable comments, you must also specify RegexOptions.IgnorePatternWhitespace, which means that non-escaped white space is ignored.Regex regex = new Regex(@"
^ # anchor at the start
(?=.*\d) # must contain at least one numeric character
(?=.*[a-z]) # must contain one lowercase character
(?=.*[A-Z]) # must contain one uppercase character
.{8,10} # From 8 to 10 characters in length
\s # allows a space
$ # anchor at the end",
RegexOptions.IgnorePatternWhitespace);
Common Regular Expressions
Some common regular expressions are shown in Table 1.Table 1. Common Regular Expressions
| Field | Expression | Format Samples | Description |
|---|---|---|---|
| Name | ^[a-zA-Z''-'\s]{1,40}$ | John Doe O'Dell |
Validates a name. Allows up to 40 uppercase and lowercase characters and a few special characters that are common to some names. You can modify this list. |
| Social Security Number | ^\d{3}-\d{2}-\d{4}$ | 111-11-1111 | Validates the format, type, and length of the supplied input field. The input must consist of 3 numeric characters followed by a dash, then 2 numeric characters followed by a dash, and then 4 numeric characters. |
| Phone Number | ^[01]?[- .]?(\([2-9]\d{2}\)|[2-9]\d{2})[- .]?\d{3}[- .]?\d{4}$ | (425) 555-0123 425-555-0123 425 555 0123 1-425-555-0123 |
Validates a U.S. phone number. It must consist of 3 numeric characters, optionally enclosed in parentheses, followed by a set of 3 numeric characters and then a set of 4 numeric characters. |
| ^(?("")("".+?""@)|(([0-9a-zA-Z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-zA-Z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,6}))$ | someone@example.com | Validates an e-mail address. | |
| URL | ^(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$ | http://www.microsoft.com | Validates a URL |
| ZIP Code | ^(\d{5}-\d{4}|\d{5}|\d{9})$|^([a-zA-Z]\d[a-zA-Z] \d[a-zA-Z]\d)$ | 12345 | Validates a U.S. ZIP Code. The code must consist of 5 or 9 numeric characters. |
| Password | (?!^[0-9]*$)(?!^[a-zA-Z]*$)^([a-zA-Z0-9]{8,10})$ | Validates a strong password. It must be between 8 and 10 characters, contain at least one digit and one alphabetic character, and must not contain special characters. | |
| Non- negative integer | ^\d+$ | 0 986 |
Validates that the field contains an integer greater than zero. |
| Currency (non- negative) | ^\d+(\.\d\d)?$ | 1.00 | Validates a positive currency amount. If there is a decimal point, it requires 2 numeric characters after the decimal point. For example, 3.00 is valid but 3.1 is not. |
| Currency (positive or negative) | ^(-)?\d+(\.\d\d)?$ | 1.20 | Validates for a positive or negative currency amount. If there is a decimal point, it requires 2 numeric characters after the decimal point. |
Additional Resources
For more information, see the regular expression tutorial at http://www.regular-expressions.info/tutorial.html.
Trovato qui.
25 March 2010
Tronca i log e compatta tutti i database (Sql2005)
-- TRONCA I LOG E COMPATTA TUTTI I DATABASE
set nocount on
USE master
GO
EXEC sp_msForEachDB '
BACKUP LOG [?] WITH TRUNCATE_ONLY
DBCC SHRINKDATABASE (''?'', TRUNCATEONLY) WITH NO_INFOMSGS
'
Versione con cursore per Sql2005:
-- TRONCA I LOG E COMPATTA TUTTI I DATABASE ONLINE -- VERSIONE PER SQL 2005 USE master GO set nocount on declare cur cursor for select name from sys.databases where database_id > 4 and state_desc = 'ONLINE' order by name open cur declare @nomeDB as nvarchar(255) fetch next from cur into @nomedb while @@fetch_status = 0 begin print 'Processing ' + @nomeDB + '...' BACKUP LOG @nomeDB WITH TRUNCATE_ONLY DBCC SHRINKDATABASE (@nomeDB, TRUNCATEONLY) WITH NO_INFOMSGS fetch next from cur into @nomedb end close cur deallocate cur print '' print 'Done.'
23 March 2010
Realizzare un AdRotator lato client con ASP.NET e jQuery
In contesti simili è possibile implementare una logica analoga sfruttando jQuery per invocare un servizio remoto e aggiornare l'interfaccia della pagina. Supponiamo allora di aver implementato, lato server, un metodo in grado di recuperare il prossimo banner da visualizzare:
[WebMethod]
public static string GetNextAdvertisement()
{
var rnd = new Random(DateTime.Now.Millisecond);
int index = rnd.Next(1, 5);
var serializer = new JavaScriptSerializer();
return serializer.Serialize(new
{
ImageUrl = string.Format("images/Banner{0}.png", index),
Url = string.Format("advertisement.ashx?idx={0}", index)
});
}Grazie all'attributo WebMethod, questo metodo viene esposto da ASP.NET come un servizio ed è invocabile lato client tramite una chiamata AJAX simile alla seguente:
function askForNewBanner() {
$.ajax({
url: "default.aspx/GetNextAdvertisement",
type: "POST",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) { updateBanner(data.d); }
});
}In pagina il banner è realizzato con un div che contiene un link e un'immagine:
<div id="adv" style="visibility:hidden">
<a href="#">
<img src="" alt="adv" />
</a>
</div>
function updateBanner(data) {
var obj = $.parseJSON(data);
$('#adv a').attr("href", obj.Url);
$('#adv a img').attr("src", obj.ImageUrl);
$('#adv').css("visibility", "visible");
}Fino ad ora, insomma, siamo riusciti a realizzare un'infrastruttura client che interroga un servizio remoto e visualizza un banner pubblicitario in pagina in base alla risposta ottenuta. A questo punto non resta che temporizzarne l'esecuzione, in modo che gli inserzionisti possano essere effettivamente ruotati anche senza che avvengano refresh di pagina, ad esempio utilizzando il plugin jQuery Timers per mostrarne uno diverso ogni 30 secondi:
$(function() {
askForNewBanner();
$(document).everyTime("30s", function() {
askForNewBanner();
});
});Trovato qui
22 March 2010
Speed Up Windows 7 Taskbar Navigation with a Registry Hack
The fundamental problem was that you needed two clicks to navigate to your document if you have two instances of a program running. Or you're stuck with hovering for what feels like an eternity.
At Windows 7 Forums I finally found a nice step in the right direction. Full post is here, but summarized below. In short, this hack causes an applications last active window to activate when you click the taskbar icon, and the next window in the second click, etc. The hover preview still works if you hover to begin with, but if you want the preview after you've click on an app's icon in the taskbar, you can Ctrl+Click to bring it back. The current default settings are the exact opposite (that is, Ctrl+Click cycles through the last active windows of an application).
- Launch regedit.exe
- Navigate in the left tree control to HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
- Go to Edit->New->DWORD (32-bit) Value
- Name the value LastActiveClick
- Hit enter to assign the value and change it to 1
- Restart Explorer and you're good to go.
To restart Explorer without rebooting, open the Task Manager (Ctrl+Shift+Esc) and end the Explorer.exe process. Then create a new task (under "File") and paste "explorer.exe".
19 March 2010
How To Replace Notepad in Windows 7
Before following the rest of this how-to, ensure that you’re logged into an account with Administrator access.
Note: The following instructions involve modifying some Windows system folders. Don’t mess anything up while you’re in there! If you follow our instructions closely, you’ll be fine.
Choose your replacement
There are a ton of great Notepad replacements, including Notepad2, Metapad, and Notepad++. The best one for you will depend on what types of text files you open and what you do with them. We’re going to use Notepad++ in this how-to.
The first step is to find the executable file that you’ll replace Notepad with. Usually this will be the only file with the .exe file extension in the folder where you installed your text editor. Copy the executable file to your desktop and try to open it, to make sure that it works when opened from a different folder.
In the Notepad++ case, a special little .exe file is available for the explicit purpose of replacing Notepad.If we run it from the desktop, it opens up Notepad++ in all its glory.
Back up Notepad
You will probably never go back once you switch, but you never know. You can backup Notepad to a special location if you’d like, but we find it’s easiest to just keep a backed up copy of Notepad in the folders it was originally located.
In Windows 7, Notepad resides in:
- C:\Windows
- C:\Windows\System32
- C:\Windows\SysWOW64 in 64-bit versions only
Paste it into the same folder.
If prompted, choose to Copy, but keep both files.
You can keep your backup as “notepad (2).exe”, but we prefer to rename it to “notepad.exe.bak”.
Do this for all of the folders that have Notepad (2 total for 32-bit Windows 7, 3 total for 64-bit).
Take control of Notepad and delete it
Even if you’re on an administrator account, you can’t just delete Notepad – Microsoft has made some security gains in this respect. Fortunately for us, it’s still possible to take control of a file and delete it without resorting to nasty hacks like disabling UAC.
Navigate to one of the directories that contain Notepad. Right-click on it and select Properties.
Switch to the Security tab, then click on the Advanced button.
Note that the owner of the file is a user called “TrustedInstaller”.
You can’t do much with files owned by TrustedInstaller, so let’s take control of it. Click the Edit… button. Select the desired owner (you could choose your own account, but we’re going to give any Administrator control) and click OK.
You’ll get a message that you need to close and reopen the Properties windows to edit permissions. Before doing that, confirm that the owner has changed to what you selected.
Click OK, then OK again to close the Properties window. Right-click on Notepad and click on Properties again.
Switch to the Security tab. Click on Edit….
Select the appropriate group or user name in the list at the top, then add a checkmark in the checkbox beside Full control in the Allow column.
Click OK, then Yes to the dialog box that pops up.
Click OK again to close the Properties window.
Now you can delete Notepad, by either selecting it and pressing Delete on the keyboard, or right-click on it and click Delete.
You’re now free from Notepad’s foul clutches!
Repeat this procedure for the remaining folders (or folder, on 32-bit Windows 7).
Drop in your replacement
Copy your Notepad replacement’s executable, which should still be on your desktop.
Browse to the two or three folders listed above and copy your .exe to those locations. If prompted for Administrator permission, click Continue.
If your executable file was named something other than “notepad.exe”, rename it to “notepad.exe”. Don’t be alarmed if the thumbnail still shows the old Notepad icon.
Double click on Notepad and your replacement should open.
To make doubly sure that it works, press Win+R to bring up the Run dialog box and enter “notepad” into the text field. Press enter or click OK.
Now you can allow Windows to open files with Notepad by default with little to no shame! All without restarting or having to disable UAC!
18 March 2010
Downlad a web page – Scaricare una pagina web – Iron AdBlock.ini update
option explicit
' -----------------------------------------------------------------------------
' PARAMETERS
' -----------------------------------------------------------------------------
const source = "http://fanboy.co.nz/adblock/iron/adblock.ini"
const destination = "C:\Program Files (x86)\SRWare Iron\adblock.ini"
' -----------------------------------------------------------------------------
UpdateAdBlock source, destination
sub UpdateAdBlock(source, destination)
' download adblock.ini
GetHtmlPage source, destination
' show message
dim s : s = ReadFirstLines(destination, 3)
MsgBox s, vbInformation, "Adblock updated"
end sub
sub GetHtmlPage (up_http, down_http)
dim xmlhttp : set xmlhttp = createobject("msxml2.xmlhttp.3.0")
xmlhttp.open "get", up_http, false
xmlhttp.send
dim fso : set fso = createobject ("scripting.filesystemobject")
dim newfile : set newfile = fso.createtextfile(down_http, true)
'and the text from the XMLHTTP response can then be written to the file:
newfile.write (xmlhttp.responseText)
'the file must then be closed:
newfile.close
set newfile = nothing
set xmlhttp = nothing
set fso = nothing
end sub
function ReadFirstLines(fileName, numberOfLines)
const wChar = "§"
dim res
' open text file
dim fso : set fso = createobject ("scripting.filesystemobject")
dim ts : set ts = fso.OpenTextFile(fileName)
' read the first x lines
dim x
for x = 1 to numberOfLines
res = res & ts.ReadLine & wChar
next
ts.close
set ts = Nothing
set fso = Nothing
' format output string
if len(res) > 1 then
res = left(res, len(res) - 1)
res = replace(res, wChar, vbCrlf)
end if
ReadFirstLines = res
end function01 March 2010
Console Screen Buffer
If you plan on making any console based games with the screen refreshing constantly you will find it flickers a lot unless you use what is known as a buffer. Here I show you a class that has a couple of functions to draw to, and then output the "image" to the console.
public class ScreenBuffer
{
//initiate important variables
public static char[,] screenBufferArray = new char[roomWidth,roomHeight]; //main buffer array
public static string screenBuffer; //buffer as string (used when drawing)
public static Char[] arr; //temporary array for drawing string
public static int i = 0; //keeps track of the place in the array to draw to
//this method takes a string, and a pair of coordinates and writes it to the buffer
public static void Draw(string text, int x, int y)
{
//split text into array
arr = text.ToCharArray(0,text.Length);
//iterate through the array, adding values to buffer
i = 0;
foreach (char c in arr)
{
screenBufferArray[x + i,y] = c;
i++;
}
}
public static void DrawScreen()
{
screenBuffer = "";
//iterate through buffer, adding each value to screenBuffer
for (int iy = 0; iy < roomHeight-1; iy++)
{
for (int ix = 0; ix < roomWidth; ix++)
{
screenBuffer += screenBufferArray[ix, iy];
}
}
//set cursor position to top left and draw the string
Console.SetCursorPosition(0, 0);
Console.Write(screenBuffer);
screenBufferArray = new char[Game.roomWidth, Game.roomHeight];
//note that the screen is NOT cleared at any point as this will simply overwrite the existing values on screen. Clearing will cause flickering again.
}
}
roomWidth and roomHeight are the width and height of your console screen respectively. This can easily be set using
Console.SetWindowSize(roomWidth,roomHeight);
Usage
Usage is very simple with this class. First of all you'll need to create the class by using
ScreenBuffer sb = new ScreenBuffer();
This simply create an instance of the ScreenBuffer class with the reference "sb" (you can change this to whatever you want). To draw to it all you need to do is use the method Draw.
ScreenBuffer.Draw("text here",x,y);
Beware that this method will not handle new lines correctly. This could be easily added by using a check within the draw function, and if it detects \n simply jump the the next line in the array. Now all you need to do is call the DrawScreen method at the end of the frame you are displaying and the array will be flushed onto the console screen, giving you a flicker free game!
~ knighty (Graeme Pollard - )
Trovato qui.