Scripts para crear comentarios en campos y tablas en SQL Server

--Ejemplos de uso:
--exec mer_listarComentariosCampos
--exec mer_listarComentariosTablas
--exec mer_ActualizarDescripcionCampo 'TABLA', 'CAMPO', 'DESCRIPCION'
--exec mer_ActualizarDescripcionTabla 'TABLA', 'DESCRIPCION'
--exec mer_EliminarDescripcionTabla 'TABLA'
--exec mer_EliminarDescripcionCampo 'TABLA', 'CAMPO'


USE [BASE]
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mer_ListarComentariosCampos]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[mer_ListarComentariosCampos]
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mer_ListarComentariosTablas]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[mer_ListarComentariosTablas]
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mer_ActualizarDescripcionTabla]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[mer_ActualizarDescripcionTabla]
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mer_ActualizarDescripcionCampo]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[mer_ActualizarDescripcionCampo]
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mer_EliminarDescripcionTabla]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[mer_EliminarDescripcionTabla]
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[mer_EliminarDescripcionCampo]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[mer_EliminarDescripcionCampo]
GO


CREATE PROCEDURE [dbo].[mer_ListarComentariosCampos]
AS

DECLARE @comentarios TABLE (
       esquema sysname,
       tabla sysname,
       columna sysname,
       descripcion VARCHAR(500))


DECLARE c CURSOR FOR
       SELECT table_schema, table_name
         FROM information_schema.tables

DECLARE @s sysname, @t sysname

OPEN c
FETCH c INTO @s, @t
WHILE @@FETCH_STATUS = 0 BEGIN
    INSERT INTO @comentarios (esquema, tabla, columna, descripcion)
             SELECT @s, @t, objname, convert(varchar(500), value)
               FROM fn_listextendedproperty (N'MS_Description', N'schema', @s, N'table', @t, N'column', null);

       FETCH c INTO @s, @t
END
CLOSE c
DEALLOCATE c

INSERT INTO @comentarios (esquema, tabla, columna)
SELECT table_schema, table_name, column_name
  FROM information_schema.columns s
 WHERE NOT EXISTS
   (SELECT *
      FROM @comentarios c
     WHERE s.table_schema = c.esquema
       AND s.table_name   = c.tabla
          AND s.column_name  = c.columna)

SELECT *
  FROM @comentarios
 ORDER BY esquema, tabla, columna


GO

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

CREATE PROCEDURE [dbo].[mer_ListarComentariosTablas]
AS

DECLARE @comentarios TABLE(tabla sysname, descripcion VARCHAR(500))
INSERT INTO @comentarios (tabla, descripcion)
SELECT objname, CONVERT(VARCHAR(500), value)
      FROM ::FN_LISTEXTENDEDPROPERTY(N'MS_DESCRIPTION', N'USER', N'DBO', N'TABLE', NULL, NULL, NULL)
INSERT INTO @comentarios (tabla)
  SELECT table_name
    FROM information_schema.tables
   WHERE table_name NOT IN
      (select tabla FROM @comentarios)

SELECT * from @comentarios ORDER BY tabla

GO

-------------------------------------------------------------------------------------------------------------
CREATE PROCEDURE [dbo].[mer_ActualizarDescripcionTabla]
-- Los parámetros son el nombre de la tabla y la descripción
@nombre_tabla sysname = '',
@descripcion_tabla sql_variant = ''
AS
BEGIN
BEGIN TRY

IF EXISTS (SELECT OBJNAME AS 'tabla', VALUE AS 'COMENTARIO'
  FROM ::FN_LISTEXTENDEDPROPERTY(N'MS_DESCRIPTION', N'USER', N'DBO', N'TABLE',
  @nombre_tabla, NULL, NULL) XP
  WHERE XP.NAME IN (N'MS_DESCRIPTION'))

EXEC sys.sp_updateextendedproperty
@name=N'MS_Description',
@value=@descripcion_tabla,
@level0type=N'SCHEMA',
@level0name=N'dbo',
@level1type=N'TABLE',
@level1name=@nombre_tabla
  ELSE
EXEC sys.sp_addextendedproperty
@name=N'MS_Description',
@value=@descripcion_tabla,
@level0type=N'SCHEMA',
@level0name=N'dbo',
@level1type=N'TABLE',
@level1name=@nombre_tabla
END TRY
BEGIN CATCH
SELECT
ERROR_LINE() as ErrorLine,
ERROR_MESSAGE() as ErrorMessage;

PRINT 'No se pudo agregar la descripción ''' + convert(nvarchar(128),@descripcion_tabla) + '''a la tabla ' + convert(nvarchar(128),@nombre_tabla)
PRINT 'Error Line: ' + convert(varchar(50),ERROR_LINE())
PRINT 'ErrorMessage: ' + ERROR_MESSAGE()
ROLLBACK TRANSACTION
END CATCH
END
GO
-------------------------------------------------------------------------------------------------------------

CREATE PROCEDURE [dbo].[mer_ActualizarDescripcionCampo]
-- Los parámetros son el nombre de la tabla, el nombre de la columna y la descripción
@nombre_tabla sysname = '',
@nombre_campo sysname = '',
@descripcion_campo sql_variant = ''
AS
BEGIN TRY
IF EXISTS(SELECT objname, value
                  FROM fn_listextendedproperty (N'MS_Description', N'schema', 'dbo',
 N'table', @nombre_tabla, N'column', null) WHERE objname = @nombre_campo)
EXEC sys.sp_updateextendedproperty
@name=N'MS_Description',
@value=@descripcion_campo,
@level0type=N'SCHEMA',
@level0name=N'dbo',
@level1type=N'TABLE',
@level1name=@nombre_tabla,
@level2type=N'COLUMN',
@level2name=@nombre_campo
ELSE
EXEC sys.sp_addextendedproperty
@name=N'MS_Description',
@value=@descripcion_campo,
@level0type=N'SCHEMA',
@level0name=N'dbo',
@level1type=N'TABLE',
@level1name=@nombre_tabla,
@level2type=N'COLUMN',
@level2name=@nombre_campo
END TRY
BEGIN CATCH
SELECT
ERROR_LINE() as ErrorLine,
ERROR_MESSAGE() as ErrorMessage;

PRINT 'No se pudo agregar la descripción ''' + convert(nvarchar(128),@descripcion_campo) + '''al campo ' + convert(nvarchar(128),@nombre_campo) + ' en la tabla ' + convert(nvarchar(128),@nombre_tabla)
PRINT 'Error Line: ' + convert(varchar(50),ERROR_LINE())
PRINT 'ErrorMessage: ' + ERROR_MESSAGE()
ROLLBACK TRANSACTION
END CATCH
GO
-------------------------------------------------------------------------------------------------------------

CREATE PROCEDURE [dbo].[mer_EliminarDescripcionTabla]
@nombre_tabla sysname = ''
AS
BEGIN TRY
EXEC sys.sp_dropextendedproperty
@name=N'MS_Description',
@level0type=N'SCHEMA',
@level0name=N'dbo',
@level1type=N'TABLE',
@level1name=@nombre_tabla
END TRY
BEGIN CATCH
SELECT
ERROR_LINE() as ErrorLine,
ERROR_MESSAGE() as ErrorMessage;

PRINT 'No se pudo agregar la descripción ''' + '''al campo ' + ' en la tabla ' + convert(nvarchar(128),@nombre_tabla)
PRINT 'Error Line: ' + convert(varchar(50),ERROR_LINE())
PRINT 'ErrorMessage: ' + ERROR_MESSAGE()
ROLLBACK TRANSACTION
END CATCH
GO
-------------------------------------------------------------------------------------------------------------

CREATE PROCEDURE [dbo].[mer_EliminarDescripcionCampo]
@nombre_tabla sysname = '',
@nombre_campo sysname = ''
AS
BEGIN TRY
EXEC sys.sp_dropextendedproperty
@name=N'MS_Description',
@level0type=N'SCHEMA',
@level0name=N'dbo',
@level1type=N'TABLE',
@level1name=@nombre_tabla,
@level2type=N'COLUMN',
@level2name=@nombre_campo
END TRY
BEGIN CATCH
SELECT
ERROR_LINE() as ErrorLine,
ERROR_MESSAGE() as ErrorMessage;

PRINT 'No se pudo agregar la descripción ''' + '''al campo ' + convert(nvarchar(128),@nombre_campo) + ' en la tabla ' + convert(nvarchar(128),@nombre_tabla)
PRINT 'Error Line: ' + convert(varchar(50),ERROR_LINE())
PRINT 'ErrorMessage: ' + ERROR_MESSAGE()
ROLLBACK TRANSACTION
END CATCH
GO
-------------------------------------------------------------------------------------------------------------

Ejecutar un webservice JSON con jQuery [Funciona!]

Este ejemplo asume que existe un webservice llamado wsX que retorna el siguiente string:

{ 'datos': [ {'nombre': 'Juan', 'direccion': 'Colonia 1212'}, {'nombre': 'Pedro', 'direccion': 'Mercedes 1111'} ] }


jQuery.ajax({
   type: "POST",
   url: http://X14/wsX/wsX.asmx/HelloWorld,
   data: "{}",
   contentType:"text",
   dataType:"text",
   cache: false,
   success: function(response) {
      var v = getJSON(response);
      alert("Resultado: " + v.datos[0].nombre);
   }
});
 
function getJSON(data)
{
   var s;

   s = data.substring(data.indexOf("{"));
   s = s.substring(0, s.lastIndexOf("}") + 1);
   return eval('(' + s + ')');
}
 

Utilizar eval para transformar texto a JSON

var data = "{ 'prueba': [ {'foo': 'The quick brown fox jumps over the lazy dog.' } ] }";


var v = eval('(' + data + ')');

alert("RESULTADO: " + v.prueba[0].foo);
 

Explicación de porqué viene una d en la respuesta JSON (otra mas)

Fuente: http://encosia.com/2009/06/29/never-worry-about-asp-net-ajaxs-d-again/

Explicación de porqué viene una d en la respuesta JSON

Fuente: http://encosia.com/2009/02/10/a-breaking-change-between-versions-of-aspnet-ajax/

Obtener datos de un web service JSON con jQuery [Funciona!]

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace Prueba1
{
    /// <summary>
    /// Descripción breve de Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // Para permitir que se llame a este servicio web desde un script, usando ASP.NET AJAX, quite la marca de comentario de la línea siguiente.
    [System.Web.Script.Services.ScriptService]
    public class Service1 : System.Web.Services.WebService
    {
        [WebMethod]
        public string HelloWorld()
        {
            return (" [{\"nombre\":\"Juan\", \"direccion\":\"Colonia 1212\"}, {\"nombre\":\"Pedro\", \"direccion\":\"Mercedes 1111\"}] ");
        }
    }
}


jQuery:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" language="javascript" src="jquery-1.3.2.min.js"></script>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Prueba personas</title>

<body>

<script type="text/javascript">

$(document).ready(function()
{

$.ajax({
 type: "POST",
 url: "http://localhost:1485/Service1.asmx/HelloWorld",
 data: "{}",
 contentType: "application/json; charset=utf-8",
 dataType: "json",
 cache: false,
 success: function(response) {
var personas = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;

for (var i = 0; i < personas.length; i++) {
alert(personas[i].nombre);
alert(personas[i].direccion);
}
 }
});


});

</script>

</body>
</html>


Fuente:
http://www.mikesdotnetting.com/Article/96/Handling-JSON-Arrays-returned-from-ASP.NET-Web-Services-with-jQuery 

Cargar div mediante jQuery y ajax

jQuery.ajax({ url: a + '_' + trn + 'conSup.vm', async: false, cache: false, success: function(){

 

Importante!! Poner cache: false, sino sólo se ejecuta la 1ra vez.

 

 

Agregar evento change a option select html con jquery

Si se accede por el nombre de los elementos (ej sel1 y boton1)

$('[name=sel1]').change(function()
     {
   $('[name=boton1]').show();
     });

Si se accede por el id:

$('#sel1').change(function() 
     {
   $('#boton1').show();
     });

Abrir un archivo con el encoding correcto en C#

        public static Encoding GetFileEncoding(string srcFile)
        {
            // *** Por defecto usar Ansi CodePage
            Encoding enc = Encoding.Default;

            byte[] buffer = new byte[5];
            FileStream file = new FileStream(srcFile, FileMode.Open);
            file.Read(buffer, 0, 5);
            file.Close();

            if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf)
                enc = Encoding.UTF8;
            else if (buffer[0] == 0xfe && buffer[1] == 0xff)
                enc = Encoding.Unicode;
            else if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff)
                enc = Encoding.UTF32;
            else if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76)
                enc = Encoding.UTF7;

            return enc;
        }

        public static StreamReader OpenStreamReaderWithEncoding(string srcFile)
        {
            Encoding enc = GetFileEncoding(srcFile);
            return new System.IO.StreamReader(srcFile, enc);
        }


Fuente: http://www.west-wind.com/Weblog/posts/197245.aspx

Acceder a blogger mediante Google API

Descargar Google Data API Setup(1.4.0.2).msi 

Código de ejemplo, agrega un post asignándole dos etiquetas:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Google.GData.Client;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] labels = {"label1", "label2"};        //labels que le quiero poner al post

            AddPost("titulo1", "body html", labels);     //titulo, cuerpo html y array de labels
        }

        public static bool AddPost(string title, string bodyHTML, string[] labels)
        {
            Service service = new Service("blogger", "");
            service.Credentials = new GDataCredentials("", "");
            AtomEntry newPost = new AtomEntry();
            newPost.Title.Text = title;
            newPost.Content = new AtomContent();
            newPost.Content.Content = bodyHTML;
            newPost.Content.Type = "html";
            foreach (string label in labels)
            {
                AtomCategory cat = new AtomCategory();
                cat.Scheme = new Uri("http://www.blogger.com/atom/ns#");
                cat.Term = label;
                newPost.Categories.Add(cat);
            }
            AtomEntry response = null;
            try
            {
                response = service.Insert(new Uri("http://expressraider.blogspot.com/feeds/posts/default"), newPost);
            }
            catch (GDataRequestException exception)
            {
                if (exception.ResponseString == "Blog has exceeded rate limit or otherwise requires word verification for new posts")
                {
                    return false;
                }
                else
                {
                    throw exception;
                }
            }
            if (response == null)
            {
                throw new Exception("Error inesperado");
            }
            return true;
        }

    }
}

Como evitar el doble enter en TinyMCE

Por defecto, cuando se presiona enter en un textarea configurada para utilizar el editor TinyMCE, se produce un doble salto de línea.

Para evitar esto, agregar en la configuración lo siguiente:

force_br_newlines : "true"

Ejemplo completo:

<script type="text/javascript">
tinyMCE.init({
mode : "textareas",
theme : "advanced",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
force_br_newlines : "true"
});
</script>