SQL Server: No regresa el texto completo en las celdas con valores tipo texto, modificar php.ini

Siguiendo con el tema del truncado de caracteres en SQL desde nuestra aplicación de PHP del post anterior, resulta que la solución también se puede hacer con el comando SQL.

SET TEXTSIZE NUMERO_CARACTERES_A_OBTENER

Pero igual si queremos algo más permanente, solo es cosa de modificar nuestro archivo PHP.ini, las lineas donde tengamos:

; Valid range 0 – 2147483647. Default = 4096.
;mssql.textlimit = 4096

; Valid range 0 – 2147483647. Default = 4096.
;mssql.textsize = 4096

Por lo general están comentadas estas lineas, solo es cosa de descomentarlas y poner el valor que deseemos, reiniciamos apache y listo :)

SQL Server: No regresa el texto completo en las celdas con valores tipo texto

Si tienes un campo de tipo texto, ya sea cualquiera de los siguientes tipos de datos:

  • varchar(max)
  • nvarchar(max)
  • varbinary(max)
  • text
  • ntext
  • image

Y cuando realizas tu select, no te regresa la información completa, entonces lo que debes de hacer es incrementar el limite de la variable textsize.

Para saber cual es el límite actual solo ejecuta el siguiente comando:

SELECT @@TEXTSIZE

Casi por default te dará un valor de 2147483647 (caracteres)

Y entonces la solución antes de ejecutar tu consulta SELECT, debes de iniciar con la siguiente consulta SQL.

SET TEXTSIZE NUMERO_CARACTERES_A_OBTENER

Digamos que deseas obtener unos 200 caracteres, entonces ejecutas SET TEXTSIZE 200 ,seguido de tu sentencia SQL del SELECT.

XAMPP no inicia el servicio Apache

Me cambie de Appserv (que tengo años usandolo) a Xampp en la computadora con Windows, ya que necesito la ultima versión estable de PHP, pero tenía un problema al iniciar el servicio de apache, xampp me indicaba que no podia usarlo porque el puerto 80 esta ocupado.

Si escribia localhost en el navegador + firebug para ver el encabezado de la petición HTTP veo la siguiente línea.

Server: Microsoft-HTTPAPI/2.0

Y la página de error:

Not Found

HTTP Error 404. The requested resource is not found.

Lo más raro de todo es que no tengo el IIS instalado, peroooo!! si tengo el SQL Server 2008 R2 que es el que da problemas., aquí la solución para desactivar el servicio que nos da lata.

Microsoft SQL Server 2008 R2 > Configuration Tools > SQL Server Configuration Manager

Una vez dentro del programa SQL Server Configuration Manager, en el menú de la izquierda: SQL Server Services seleccionamos la opción donde aparezca:

SQL Server Reporting Services (MSSQLSERVER) botón derecho y Stop.

Ahora, para que no de lata al momento de reiniciar windows, tenemos que desactivar por completo el inicio automatico del proceso., solo doble click y aparecerá una ventana con pestañas:

Service > Start Mode: Disabled

Aceptar y listo!!.., si no funciona, reiniciamos Windows (para variar)… apache ready!

SQLServer: Error al comparar 2 campos con diferente collation (idioma)

Si estas comparando 2 tablas de diferentes bases de datos, y cada una tiene su propio idioma o collation como lo llama Microsoft (la vda no se bien que signifique pero es algo del encoding). y pues te sale este mensaje:

SQL EXecution Error.
Executed SQL statement: SELECT * FROM tabla…..
Error Source: .Net SqlCliente Data Provider
Error Message: Cannot resolve the collation conflict between
“Modern_Spanish_CI_AS” and “SQL_Latin1_General_CP1_CI_AS” in the equal to operation.

LA solución es poner en tu WHERE el tipo de collation que quieres utilizar para que haga la conversión SQL Server, teniendo algo como esto:

SELECT * FROM tabla, tabla2 WHERE tabla1.campo1 COLLATE Modern_Spanish_CI_AS = tabla2.campo2 COLLATE Modern_Spanish_CI_AS

Bueno la consulta no es la mejor! tendria que esta en un INNER JOIN pero jeje, este no es el tema., y listo! la consulta ya funciona., no se si luego existan problemas con acentos o caracteres raros, pero para texto casi normal, no debería de fallar.

Codeigniter: Modificar LIMIT para el driver MSSQL

Después de encontrar la solución para que funcione el LIMIT de MySQL en Microsoft SQL Server ahora sigue el turno de modificar el código de Codeigniter para así tener algo transparente para nuestras consultas SQL.

Lo primero que se debe de hacer es modificar la librería de carga del Codeigniter, ( $this->load-> )
Vamos a trabajar en la carpeta: /system/application/libraries/ y creamos un archivo llamado: MY_Loader.php con el siguiente código:

< ?php
class MY_Loader extends CI_Loader{
/
* Constructor, calls parent constructor.
*/
function MY_Loader()
{
parent::CI_Loader();
}

/
* Database Loader
*
* @access public
* @param string the DB credentials
* @param bool whether to return the DB object
* @param bool whether to enable active record (this allows us to override the config setting)
* @return object
*/
function database($params = '', $return = FALSE, $active_record = FALSE)
{
// Do we even need to load the database class?
if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE)
{
return FALSE;
}

require_once(BASEPATH.'database/DB'.EXT);

// Load the DB class
$db =& DB($params, $active_record);

$my_driver = config_item('subclass_prefix').'DB_'.$db->dbdriver.’_driver’;
$my_driver_file = APPPATH.’libraries/’.$my_driver.EXT;

if (file_exists($my_driver_file))
{
require_once($my_driver_file);
$db =& new $my_driver(get_object_vars($db));
}

if ($return === TRUE)
{
return $db;
}
// Grab the super object
$CI =& get_instance();

// Initialize the db variable. Needed to prevent
// reference errors with some configurations
$CI->db = ”;
$CI->db = $db;
// Assign the DB object to any existing models
$this->_ci_assign_to_models();
}

}

La idea de este archivo es extender la funcionalidad de carga de los drivers para la base de datos, despues en la misma carpeta de libraries creamos un archivo llamado: MY_DB_mssql_driver.php ya que estamos usando el driver mssql para nuestra conexión SQL Server

< ?php

class MY_DB_mssql_driver extends CI_DB_mssql_driver {

function __construct($params){
parent::__construct($params);
log_message('debug', 'Extended DB driver class instantiated!');
}

function _limit($sql, $limit, $offset){
if($offset == 0){
return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$limit.' ', $sql);
}else{
$OrderBy = "ORDER BY ";
if (count($this->ar_orderby) > 0){
$OrderBy .= implode(‘, ‘, $this->ar_orderby);

if ($this->ar_order !== FALSE)
{
$OrderBy .= ($this->ar_order == ‘desc’) ? ‘ DESC’ : ‘ ASC’;
}
}else{
$OrderBy .= “(SELECT 1)”;
}

$sql = preg_replace(‘/(\\’. $OrderBy .’\n?)/i’,”, $sql);
$sql = preg_replace(‘/(^\SELECT (DISTINCT)?)/i’,'\\1 ROW_NUMBER() OVER (‘.$OrderBy.’) AS rownum, ‘, $sql);
return “SELECT * \nFROM (\n” . $sql . “) AS A \nWHERE A.rownum BETWEEN (” .($offset + 1) . “) AND (“.($offset + $limit).”)”;
}
}

Y listo! con esto nuestra consulta LIMIT será transparente y se usará como siempre: $this->db->limit(2,10);

Aca les dejo las fuentes de esta información:

No existe offset (antes decia: LIMIT) en MS SQL Server

Así como suena el titulo, en Microsoft SQL Server no existe la función limit , para implementarla tienes que usar algunos trucos con subconsultas., algo tan sencillo en MySQL como: SELECT * FROM miTabla LIMIT 2,10 en SQL Server se vuelve una calamidad.

Buscando en Internet, encontré en Foros del Web una explicación de como hacer funcionar, se tiene que poner una subconsulta SQL con algo que diga: ROW_NUMBER() OVER (ORDER BY campo) as NumRows y despues se hace un WHERE con su respectivo Between para poner el limite: WHERE NumRows BETWEEN 2 AND 10

Aca un ejemplo más elaborado:

SELECT *
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY mi_Campo1) AS NumRows, *
FROM mi_Tabla
) as AS_NumRows
WHERE AS_NumRows.NumRows BETWEEN 10 AND 20

Si se requiere algún WHERE en nuestra consulta SQL se debe de meter en la subquery, en caso que no tengamos ningun campo a ordenar se cambia lo que tiene ROW_NUMBER, ORDER BY por la siguiente información:

ROW_NUMBER() OVER (ORDER BY (SELECT 1))

Y listo!.., no he probado el rendimiento pero pues aquí una solución extra.