martes, 11 de abril de 2017

SQL - Ejecutar Showplan


El showplan sirve para detectar por ejemplo:

Table Scan:
Significa que el motor tiene que leer toda la tabla. Esto solo puede suceder cuando la tabla es Heap (o sea, no tiene un índice clustered). En algunos casos, cuando es una tabla chica, un Table Scan es la mejor opción, ya que produce poco overhead. De hecho la tabla puede tener índices y sin embargo el SQL elige usar un table scan porque sería más rápido. Pero cuando la tabla es más grande, no debería haber Table Scan, ya que es muy costoso. Para solucionar este problema, hay ver si la tabla tiene índices y si se están usando correctamente. Lo importante es prestarle atención cuando vemos un table Scan. Muchas veces, nuestro problemas de performance pasan por ahí.-

Clustered Index Scan:
Esta operación es muy similar a un table scan. El motor recorre toda la tabla. La diferencia entre uno y otro, es que el Clustered Index Scan se realiza en una tabla que tiene un índice Clustered y el Table Scan en una tabla que no tiene este tipo de indice.
Otra vez tenemos que evaluar si esta opción es la que realmente queremos. Muchas veces, por un mal uso de los índices, se ejecuta esta operación, cuando en realidad queríamos otra más eficiente.

Clustered Index Seek: 
Si vemos esta operación, en general, podemos estar contentos. Significa que el motor está usando efectivamente el índice Clustered de la tabla.

Index Seek: 
Aquí también si vemos esta operación, podemos estar contentos. Es similar que el Clustered Index Seek, pero con la diferencia de que se usa un indice Non Clustered.

Index Scan:
Esta operación se ejecuta cuando se lee el índice completo de una tabla. Es preferible a un Table Scan, ya que obviamente leer un indice es mas chico que una tabla. Esta operación puede ser síntoma de un mal uso del índice, aunque también puede ser que el motor haya seleccionado que esta es la mejor operación. Es muy común un Index Scan en un join o en un ORDER BY o GROUP BY.

Bookmark Lookup:
Esta es una operación muy importante, donde hay algunas diferencias entre 2000 y 2005 que vale la pena saber. El Bookmark Lookup indica que SQL Server necesita ejecutar un salto del puntero desde la página de índice a la página de datos de la tabla para recuperar los datos. Esto sucede siempre que tenemos un índice Non Clustered. Para evitar esta operación, hay que limitar los campos que queremos traer en la consulta.
Si el campo que vamos a extraer, esta fuera del índice, entonces se va a ejecutar esta operación y no queda otra opción (para SQL Server 2000). Acá reside la importancia de evitar los SELECT * FROM …




MODO DE EJECUCIÓN DEL SHOW PLAN



Muestra el show plan en formato texto

jueves, 6 de abril de 2017

C# - Jquery Grid activar orden (sort) en encabezados de una grilla.-

 var lastsel;
        function defineGridOp() {
            try {
                $("#grid_op").jqGrid({
                    caption: "Nominas",
                    datatype: "local",
                    colNames: ['Nómina', 'Estado', 'Fecha Nómina', 'Total Nómina'],
                    colModel: [
                        { name: 'numero_nomina', index: 'numero_nomina', width: '150px', align: 'center', formatter: 'number', sorttype: 'number', formatoptions: { decimalPlaces: 0} },
                        { name: 'estado', index: 'estado', align: 'center', width: '200px', editable: false, hidden: false },
                        { name: 'fecha_nomina', index: 'fecha_nomina', width: '200px', align: 'center', editable: false, hidden: false, formatter: 'date', formatoptions: { newformat: 'd/m/Y' } },
                        { name: 'total_nomina', index: 'total_nomina', width: '300px', align: 'center', formatter: 'number',sorttype: 'number', formatoptions: { decimalPlaces: 0 } }
                    ],
                    multiselect: true,
                    rowNum: 200,
                    pgbuttons: true,
                    pager: $('#pager2'),
                    viewrecords: true,
                    width: 950,
                    shrinkToFit: false,
                    autowidth: false,
                    onSortCol: true,
                    forceFit: true,
                    height: 400,
                    editurl: jutils.pageName(),
                    deselectAfterSort: false,
                    onSelectRow: function (id, status) {
                        if (id && id !== lastsel) {
                            $('#grid_op').jqGrid('restoreRow', lastsel);
                        }
                    }
                });
                $("#grid_op").jqGrid('navGrid', "#pager2", { edit: false, add: false, del: false, refresh: false, search: false });
                $("#grid_op").jqGrid('navButtonAdd', '#pager2', { buttonicon: 'ui-icon-document', onClickButton: function () { Ver(); }, caption: ' Reimprimir Nómina ', title: ' Reimprimir Nómina ' });
                $("#grid_op").jqGrid('navButtonAdd', '#pager2', { buttonicon: 'ui-icon-document', onClickButton: function () { Exportar(); }, caption: '  Excel', title: ' Exportar ' });
                $("#grid_op").jqGrid('navButtonAdd', '#pager2', { buttonicon: 'ui-icon-document', onClickButton: function () { Ver2(); }, caption: '  Detalle', title: ' Report e' });
             
            } catch (e) {
                jutils.showError(e, arguments.callee.name);
            }
        }

miércoles, 5 de abril de 2017

C# - Celdas editables grilla jquery (edición inline)

.ASPX

var lastsel;
        function defineGridImp() {
            try {
                $("#grvGeneraHCP").jqGrid({
                    colNames: ['Operación', 'N° HCP', 'Provisión', 'Desc. Concepto', 'Emisión', 'Monto $', 'Moneda', 'Paridad', 'Monto Mo', 'Beneficiario', 'Banco', 'Swift', 'Account', 'Referente', 'Observaciones', 'cod. importacion'],
                    colModel: [{ name: 'operacion', index: 'operacion', width: '80px', hidden: false },
                               { name: 'correl_hcp', index: 'correl_hcp', width: '70px', hidden: false },
                               { name: 'tipo_prov_desc', index: 'tipo_prov_desc', width: '90px', hidden: false },
                               { name: 'desc_concepto', index: 'desc_concepto', width: '120px', align: 'center', editable: false, hidden: false },
                               { name: 'fecha_emision', index: 'fecha_emision', width: '90px', align: 'center', editable: false, hidden: false },
                               { name: 'neto_', index: 'neto_', width: '90px', align: 'right', editable: false, hidden: false, formatter: 'currency', formatoptions: { decimalPlaces: 0} },
                               { name: 'sigla_moneda', index: 'sigla_moneda', width: '80px', hidden: false },
                               { name: 'valor_paridad', index: 'valor_paridad', width: '90px', align: 'right', editable: false, hidden: false, formatter: 'currency', formatoptions: { decimalPlaces: 2} },
                               { name: 'monto_mo', index: 'monto_mo', width: '90px', align: 'right', editable: false, hidden: false, formatter: 'currency', formatoptions: { decimalPlaces: 0} },
                               { name: 'nombre_beneficiario', index: 'nombre_beneficiario', width: '90px', hidden: false },
               { name: 'banco', index: 'banco', width: '80px', editable: true,editoptions:{maxlength:"150"}, hidden: false },
  { name: 'swift', index: 'swift', width: '80px', editable: true,editoptions:{maxlength:"150"}, hidden: false },
  { name: 'account', index: 'account', width: '80px', editable: true,editoptions:{maxlength:"150"}, hidden: false },
  { name: 'referente', index: 'referente', width: '80px',editable: true,editoptions:{maxlength:"150"}, hidden: false },
  { name: 'observacion', index: 'observacion', width: '80px', editable: true,editoptions:{maxlength:"150"}, hidden: false },
  { name: 'id_importacion', index: 'id_importacion', width: '80px', editable: false ,hidden: true }
                               ],
                    multiselect: true,
                    loadtext: 'Cargando datos...',
                    emptyrecords: 'No hay resultados encontrados para filtros indicados',
                    viewrecords: true,
                    pager: $('#pieDeGrilla'),
                    //                    rowNum: 100,
                    //                    rowList: [100, 200, 300],
                    width: 1100,
                    shrinkToFit: false,
                    autowidth: false,
                    forceFit: false,
                    height: 500,
                    editurl: jutils.pageName(),
                    userDataOnFooter: true,
                    onSelectRow: function (id, status) {
                        if (id && id !== lastsel) {
                            $('#grvGeneraHCP').jqGrid('restoreRow', lastsel);

                        }
                        jQuery("#grvGeneraHCP").jqGrid('editRow', id,true);

                    }
                });
                $("#grvGeneraHCP").jqGrid('filterToolbar', { stringResult: false, searchOnEnter: false, defaultSearch: 'cn' });
                $("#grvGeneraHCP").jqGrid('navGrid', "#pieDeGrilla", { edit: false, add: false, del: false, refresh: false });
                $("#grvGeneraHCP").jqGrid('navButtonAdd', '#pieDeGrilla', { buttonicon: 'ui-icon-transferthick-e-w', onClickButton: function () { Generar(); }, caption: 'Reimprimir', position: 'last', title: 'Procesar', cursor: 'pointer' });

            } catch (e) {
                jutils.showError(e, arguments.callee.name);
            }
        }


//Una forma de extraer el valor en .CS seria:
#region GENERAR
        [WebMethod]
        public static string GenerarHCP(object data)
        {
            string[] mensaje;
            var numHcp = 0;
            int iusuario = ((UserSessionObjectBc)HttpContext.Current.Session["UserSessionObjectBc"]).CodPersonal;
            var filename = string.Empty;

            DataSet ds = null;
            try
            {
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                serializer.MaxJsonLength = Int32.MaxValue;
                string json = serializer.Serialize(data);
                dynamic selectedRows = JsonConvert.DeserializeObject(json);

                DataTable dt = new DataTable();
                dt.Columns.Add("correlativo_hcp", typeof(decimal));
                dt.Columns.Add("modoPago", typeof(int));
                dt.Columns.Add("codBanco", typeof(int));
                dt.Columns.Add("cuentaCorriente", typeof(string));
                dt.Columns.Add("cuentaContable", typeof(int));
                dt.Columns.Add("rutProveedor", typeof(string));
                dt.Columns.Add("nombreProveedor", typeof(string));
                dt.Columns.Add("rutBeneficiario", typeof(string));
                dt.Columns.Add("nombreBeneficiario", typeof(string));
                dt.Columns.Add("banco", typeof(string));
                dt.Columns.Add("swift", typeof(string));
                dt.Columns.Add("account", typeof(string));
                dt.Columns.Add("referente", typeof(string));
                dt.Columns.Add("observacion", typeof(string));
                dt.Columns.Add("idimportacion", typeof(string));
                dt.Columns.Add("monto", typeof(decimal));
                dt.Columns.Add("idusuario", typeof(int));


                foreach (dynamic rowGrid in selectedRows)
                {
                    if (rowGrid != null)
                    {
                        DataRow rowDt = dt.NewRow();
                        string _correl_hcp = rowGrid.correl_hcp;
                        decimal _correl_hcp_ = Convert.ToDecimal(_correl_hcp);
                        rowDt["correlativo_hcp"] = _correl_hcp_;
                        rowDt["modoPago"] = 0;
                        rowDt["codBanco"] = 0;
                        rowDt["cuentaCorriente"] = String.Empty;
                        rowDt["cuentaContable"] = 0;
                        rowDt["rutProveedor"] = String.Empty;
                        rowDt["nombreProveedor"] = String.Empty;
                        rowDt["rutBeneficiario"] = String.Empty;
                        rowDt["nombreBeneficiario"] = rowGrid.nombre_beneficiario;

//si el usuario guarda en la grilla registros editados con ENTER, toma solo el valor ingresado, en caso //contrario toma el text completo, por eso se aplica el SPLIT.-
                       var cellBanco = rowGrid.banco.ToString();
                        if (cellBanco != string.Empty)
                        {
                            if (cellBanco.Contains("value="))
                            {
                                cellBanco = cellBanco.Split(new string[] { "value=" }, StringSplitOptions.None)[1];
                                cellBanco = cellBanco.Split(new string[] { "maxLength=" }, StringSplitOptions.None)[0];
                                cellBanco = cellBanco.Replace(@"\", "");
                                cellBanco = cellBanco.Replace(@"""", "");
                                rowDt["banco"] = cellBanco;
                            }
                            else if (cellBanco.Contains("maxLength="))
                                rowDt["banco"] = string.Empty;
                            else
                                rowDt["banco"] = cellBanco;

                        }
                        else
                            rowDt["banco"] = string.Empty;

                        var cellSwift = rowGrid.swift.ToString();
                        if (cellSwift != string.Empty)
                        {
                            if (cellSwift.Contains("value="))
                            {
                                cellSwift = cellSwift.Split(new string[] { "value=" }, StringSplitOptions.None)[1];
                                cellSwift = cellSwift.Split(new string[] { "maxLength=" }, StringSplitOptions.None)[0];
                                cellSwift = cellSwift.Replace(@"\", "");
                                cellSwift = cellSwift.Replace(@"""", "");
                                rowDt["swift"] = cellSwift;
                            }
                            else if (cellSwift.Contains("maxLength="))
                                rowDt["swift"] = string.Empty;
                            else
                                rowDt["swift"] = cellSwift;
                        }
                        else
                            rowDt["swift"] = cellSwift;

                        var cellAccount = rowGrid.account.ToString();
                        if (cellAccount != string.Empty)
                        {
                            if (cellAccount.Contains("value="))
                            {
                                cellAccount = cellAccount.Split(new string[] { "value=" }, StringSplitOptions.None)[1];
                                cellAccount = cellAccount.Split(new string[] { "maxLength=" }, StringSplitOptions.None)[0];
                                cellAccount = cellAccount.Replace(@"\", "");
                                cellAccount = cellAccount.Replace(@"""", "");
                                rowDt["account"] = cellAccount;
                            }
                            else if (cellAccount.Contains("maxLength="))
                                rowDt["swift"] = string.Empty;
                            else
                                rowDt["swift"] = cellAccount;
                        }
                        else
                            rowDt["account"] = string.Empty;

                        var cellReferente = rowGrid.referente.ToString();
                        if (cellReferente != string.Empty)
                        {
                            if (cellReferente.Contains("value="))
                            {
                                cellReferente = cellReferente.Split(new string[] { "value=" }, StringSplitOptions.None)[1];
                                cellReferente =
                                    cellReferente.Split(new string[] { "maxLength=" }, StringSplitOptions.None)[0];
                                cellReferente = cellReferente.Replace(@"\", "");
                                cellReferente = cellReferente.Replace(@"""", "");
                                rowDt["referente"] = cellReferente;
                            }
                            else if (cellReferente.Contains("maxLength="))
                                rowDt["referente"] = string.Empty;
                            else
                                rowDt["referente"] = cellReferente;
                        }
                        else
                            rowDt["referente"] = string.Empty;

                        var cellObservacion = rowGrid.observacion.ToString();
                        if (cellObservacion != string.Empty)
                        {
                            if (cellObservacion.Contains("value="))
                            {
                                cellObservacion =
                                    cellObservacion.Split(new string[] { "value=" }, StringSplitOptions.None)[1];
                                cellObservacion =
                                    cellObservacion.Split(new string[] { "maxLength=" }, StringSplitOptions.None)[0];
                                cellObservacion = cellObservacion.Replace(@"\", "");
                                cellObservacion = cellObservacion.Replace(@"""", "");
                                rowDt["observacion"] = cellObservacion;
                            }
                            else if (cellObservacion.Contains("maxLength="))
                                rowDt["observacion"] = string.Empty;
                            else
                                rowDt["observacion"] = cellObservacion;



                        }
                        else
                            rowDt["observacion"] = string.Empty;

                        rowDt["idimportacion"] = rowGrid.id_importacion;
                        var valor = rowGrid.neto_ != null && rowGrid.neto_ != string.Empty ? Convert.ToDecimal(rowGrid.neto_) : Convert.ToDecimal(0);
                        rowDt["monto"] = valor;
                        rowDt["idusuario"] = iusuario;
                        dt.Rows.Add(rowDt);;
                    }
                }

                if (dt.Rows.Count != 0)
                {
                    #region Genera HCP Importación
                    try
                    {
                        numHcp = new BcPagoProveedores().InsertHcpImportacionesNuevo(dt);
                    }
                    catch (Exception exc)
                    {
                        new Exception(exc.Message.ToString());
                    }
                    #endregion
                }

                if (numHcp > 0)
                {
                    ds = new BcPagoProveedores().GetInformeHcpImportaciones(numHcp);
                    //ds.WriteXml(@"C:\CR\InformeHcpImportaciones.xml");

                    DataTable reporte = new CR().RecuperaReporte(Convert.ToInt32(10030));
                    if (reporte != null && reporte.Rows.Count > 0)
                    {
                        if (ds != null)
                        {
                            if (ds.Tables.Count == 0 || ds.Tables[0].Rows.Count == 0)
                            {
                                filename = "SD";
                            }
                            else
                            {
                                filename = new FuncionesGenericas().GeneraPdf(ds, reporte);
                            }
                        }
                    }
                }

            }
            catch (Exception exc)
            {
                filename = "*" + exc.Message.ToString() + "*";
            }
            return JsonConvert.SerializeObject(filename);
        }
        #endregion

    }




--Actualización 26/04/2017
//si el usuario guarda en la grilla registros editados con ENTER, toma solo el valor ingresado, en caso //contrario toma el text completo, por eso se aplica el SPLIT.-

//Para evitar esta situación se puede agregar la propiedad
jQuery(gridRef).jqGrid('saveRow', selectedRowsIds[i]);
//En el archivo Jutils.js de mi proyecto, se gatilla al manipular la grilla en la funcion:
//

//Esta fuerza la función del ENTER guardando los registros en la memoria de la grilla.-

//En el proyecto se agrega en la función de la grilla.-
//EJ:
jutils.grid = {
    selectedRows: function (gridRef) {
        var selectedRowsIds = $(gridRef).jqGrid('getGridParam', 'selarrrow');
        var selectedRows = [];

        for (var i = 0; i < selectedRowsIds.length; i++) {
            jQuery(gridRef).jqGrid('saveRow', selectedRowsIds[i]);
            var row = $(gridRef).jqGrid('getRowData', selectedRowsIds[i]);
            selectedRows.push(row);
        }
        return selectedRows;
    },
    allRows: function (gridRef) {
        var selectedRows = $(gridRef).jqGrid('getRowData');
        return selectedRows;








lunes, 3 de abril de 2017

C# - Obtener URL de forma dinámica en sitio publicado de forma virtual

  /// <summary>
  /// MapPathUrlDinamico 
  /// </summary>
  /// <param name="url">ejemplo:Visor/Informes.aspx</param>       
 /// <returns>URL COMPLETA DINAMICA</returns>
        public string MapPathUrlDinamico(string url)
        {
            var urlCompleta = HttpContext.Current.Request.Url.OriginalString.Substring(0, HttpContext.Current.Request.Url.OriginalString.IndexOf("Paginas")) + url;
            return urlCompleta;
        }

//NOTA:
var urlCompleta = HttpContext.Current.Request.Url.OriginalString.Substring(0, HttpContext.Current.Request.Url.OriginalString.IndexOf("Paginas"))
//Obtiene la URL desde "PAGINAS" hacia atras.-