mercoledì 31 luglio 2013

C# - Convertire un numero in una base qualsiasi

Recentemente ho dovuto sviluppare un'integrazione con il servizio di spedizioni SDA. Per la generazione di alcuni Tracking Number ho dovuto creare dei progressivi, utilizzando una sequenza di numeri e lettere, secondo le specifiche di SDA.

Questo mi ha portato a voler creare una funzione di supporto per poter convertire un numero in una base qualsiasi, determinata da ad un array di caratteri.


        /// <summary>
        /// Converts a value to a custom base.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="baseChars">The base chars.</param>
        /// <returns></returns>
        private static string ConvertToBase(int value, char[] baseChars)
        {
            string result = string.Empty;
            int targetBase = baseChars.Length;

            do
            {
                result = baseChars[value % targetBase] + result;
                value = value / targetBase;
            }
            while (value > 0);

            return result;
        }


Per convertire ad esempio un numero es 8258, in base 2 basta scrivere


int value = 8258;
string baseTwoResult = ConvertToBase(value, new char[] { '0', '1' });


Il risultato sarà "10000001000010"



Per convertire un numero secondo la base di SDA ho dovuto fare così:

int value = 8258;
var chars = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
string baseSDAResult = ConvertToBase(value, chars);

Il risultato è : "GNO"


Spero possa essere utile anche a qualcun altro.

lunedì 22 luglio 2013

Sostituire un testo in tutti i campi del database SQL Server

Per sostituire un testo in tutti i campi di un database SQL server potete usare il seguente script.
La sostituzione NON avviene in automatico, ma avrete come risultato tutte le query di sostituzione necessarie :


DECLARE @SearchStr nvarchar(MAX)
SET @SearchStr = 'text to search'

DECLARE @ReplaceStr nvarchar(MAX)
SET @ReplaceStr = 'replace text'

 CREATE TABLE #Results (
  TableName nvarchar(370), 
  ColumnName nvarchar(370), 
  ColumnValue nvarchar(MAX))

 SET NOCOUNT ON

 DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
 SET  @TableName = ''
 SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')

 WHILE @TableName IS NOT NULL
 BEGIN
  SET @ColumnName = ''
  SET @TableName = 
  (
   SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
   FROM  INFORMATION_SCHEMA.TABLES
   WHERE   TABLE_TYPE = 'BASE TABLE'
    AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
    AND OBJECTPROPERTY(
      OBJECT_ID(
       QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
        ), 'IsMSShipped'
             ) = 0
  )

  WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
  BEGIN
   SET @ColumnName =
   (
    SELECT MIN(QUOTENAME(COLUMN_NAME))
    FROM  INFORMATION_SCHEMA.COLUMNS
    WHERE   TABLE_SCHEMA = PARSENAME(@TableName, 2)
     AND TABLE_NAME = PARSENAME(@TableName, 1)
     AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'ntext')
     AND QUOTENAME(COLUMN_NAME) > @ColumnName
   )
 
   IF @ColumnName IS NOT NULL
   BEGIN
    INSERT INTO #Results
    EXEC
    (
     'SELECT ''' + @TableName + '''' + ', ''' + @ColumnName + ''', CONVERT(NVARCHAR(MAX), ' + @ColumnName + ') 
     FROM ' + @TableName + ' (NOLOCK) ' +
     ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
    )
   END
  END 
 END

 SELECT DISTINCT 'UPDATE ' + TableName + ' SET ' +  ColumnName + ' = REPLACE(CONVERT(NVARCHAR(MAX), ' + ColumnName + '), ''' + @SearchStr + ''', ''' +  @ReplaceStr + ''' )' FROM #Results
 
 
 DROP TABLE #Results

Questo script mi è sempre risultato molto utile per sostituire link che tra il mio ambiente di sviluppo e quello di produzione sono diversi.