Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Campo bool o booleano en tabla de sql server

17,691 views
Skip to first unread message

Pedro

unread,
Sep 9, 2008, 10:48:37 AM9/9/08
to
Quiero un campo en una tabla que me represente un flag o valor bool (true o
false). Cuales es la mejor alternativa? Bit? Tinyint? Char?

Gustavo Larriera (MVP)

unread,
Sep 9, 2008, 1:16:02 PM9/9/08
to
Por una cuestion de gusto personal, prefiero usar el tipo BIT.

--
Gustavo Larriera, Microsoft MVP
http://www.linkedin.com/in/gustavolarriera
--
Este mensaje se proporciona tal como es, sin garantías de ninguna clase.

Rubén Garrigós

unread,
Sep 9, 2008, 2:14:01 PM9/9/08
to
Hola Pedro,

Yo también te recomiendo el tipo bit por motivos técnicos. El almacenamiento
en SQL Server de los campos de tipo bit en una tabla se realiza de forma
empaquetada. Esto quiere decir que aunque tengamos 8 campos de tipo bit en la
misma tabla el espacio que nos ocupa físicamente seguirá siendo el mismo (se
consume únicamente 1 byte por cada 8 columnas de dicho tipo).

Rubén Garrigós
Solid Quality Mentors

Pedro

unread,
Sep 9, 2008, 2:22:41 PM9/9/08
to
Cierta vez leí algo sobre que por la portabilidad o algo parecido no se
recomendaban los campos Bit.
Es cosa del pasado me imagino.


"Rubén Garrigós" <RubnG...@discussions.microsoft.com> escribió en el
mensaje news:224B2EA1-A2F9-45F5...@microsoft.com...

Maxi Accotto

unread,
Sep 10, 2008, 8:00:07 PM9/10/08
to
Hola, yo uso char(1) y pongo S o N.

--

Saludos
-----------------------------------------------------------------------
Maxi Accotto
Microsoft MVP en SQLServer
SQltotalconsulting
-------------------------------------------------------------------

"Pedro" <pedri...@hotmail.es> escribió en el mensaje de
noticias:e5QeksoE...@TK2MSFTNGP02.phx.gbl...

Unknown

unread,
Sep 11, 2008, 9:22:51 AM9/11/08
to
Para mi lo mas efectivo seria usar Bit.

Segun Libros de SQL:

********************************************************************
Bit:
Tipo de datos entero 1, 0 ó NULL.
Observaciones
Microsoft® SQL ServerT optimiza el almacenamiento que utilizan las columnas
de tipo bit. Si hay 8 ó menos columnas de tipo bit en una tabla, las
columnas se almacenan como 1 byte. Si hay entre 9 y 16 columnas de tipo bit,
se almacenan como 2 bytes y así sucesivamente.

********************************************************************

Osea que si en una tabla tenes hasta 8 columnas bit, solo ocuparas 1 byte.

Pero si lo guardas como char(1) vas a usar 8 bytes.

Saludos

Waldo


Maxi Accotto

unread,
Sep 11, 2008, 7:39:07 PM9/11/08
to
Si es cierto, pero bit no siempre es facil de manejar desde las aplicaciones
o bien cuando necesitas ir hacia otros motores, char(1) es mas standard :)

--

Saludos
-----------------------------------------------------------------------
Maxi Accotto
Microsoft MVP en SQLServer
SQltotalconsulting
-------------------------------------------------------------------

"Waldo" <[waldodj2000] a r r o b a [yahoo Punto com Punto ar]> escribió en
el mensaje de noticias:Olz6JIB...@TK2MSFTNGP06.phx.gbl...

Unknown

unread,
Sep 12, 2008, 9:26:24 AM9/12/08
to
Ah, eso puede ser


Gustavo Larriera (MVP)

unread,
Sep 12, 2008, 7:01:02 PM9/12/08
to
No comparto tu idea, querido amigo Maxi.

Usar 'S' o 'N' no es demasiado bueno. Imaginemos que la base es usada por
personas que hablen inglés por ejemplo... además de lidiar con la
sensibilidad de mayúsculas/minúsculas, además de tener que poner más
"inteligencia" en las aplicaciones para enteneder que 'S' es verdadero y 'N'
es falso.

Si no se quiere usar BIT por una cuestión de ser un tipo demasiado
propietario de SQL Server, entonces es preferible usar algún tipo integer que
es un tipo de datos disponible en cualquier sistema.

Y luego almacenar con 0 (FALSE) y un valor no-cero para TRUE (prefiero 1),
siguiendo la idea clásica de C90.

--
Gustavo Larriera, Microsoft MVP
http://www.linkedin.com/in/gustavolarriera
--
Este mensaje se proporciona tal como es, sin garantías de ninguna clase.

Carlos M. Calvelo

unread,
Sep 12, 2008, 7:45:58 PM9/12/08
to
Hola Gustavo,

On 13 sep, 01:01, Gustavo Larriera (MVP)


<GustavoLarriera...@discussions.microsoft.com> wrote:
> No comparto tu idea, querido amigo Maxi.
>
> Usar 'S' o 'N' no es demasiado bueno. Imaginemos que la base es usada por
> personas que hablen inglés por ejemplo... además de lidiar con la
> sensibilidad de mayúsculas/minúsculas, además de tener que poner más
> "inteligencia" en las aplicaciones para enteneder que 'S' es verdadero y 'N'
> es falso.
>
> Si no se quiere usar BIT por una cuestión de ser un tipo demasiado
> propietario de SQL Server, entonces es preferible usar algún tipo integer que
> es un tipo de datos disponible en cualquier sistema.
>
> Y luego almacenar con 0 (FALSE) y un valor no-cero para TRUE (prefiero 1),
> siguiendo la idea clásica de C90.
>

Otras consideraciones:

Si se tienen muchas columnas de este tipo habrá que considerar el
espacio que ocupan (mejor usar BIT). Si se suelen pedir muchos
registros
a la vez habrá que considerar la eficiencia. Supongo que cuesta mas
'empaquetar' y 'desempaquetar' los BIT (que, creo, resultan en tipo
numérico (int?)), que simplemente tener INT.
(No lo sé. Solo un par de ideas, porque habría que hacer pruebas)

En cuanto al razonamiento del idioma, tambien se puede tener '0' y '1'
(char) en vez de 0 y 1 (int). O 'T' / 'F'

Y, last but no least, no se pueden definir índices con columnas tipo
BIT.

Saludos,
Carlos

Carlos M. Calvelo

unread,
Sep 12, 2008, 8:08:49 PM9/12/08
to
Ah!
Y crear un User defined type 'Boolean' con una restricción (rule)
y usar ese tipo consecuentemente a la hora de definir las tablas.

Por ejemplo 'Boolean' basado en char(5) y con una restricción
@value IN ('true', 'false')

Saludos,
Carlos

Gustavo Larriera (MVP)

unread,
Sep 12, 2008, 8:45:00 PM9/12/08
to
Hola Carlos,


"Carlos M. Calvelo" wrote:

>
> En cuanto al razonamiento del idioma, tambien se puede tener '0' y '1'
> (char) en vez de 0 y 1 (int). O 'T' / 'F'
>

Lo que me gusta de usar 0/1 por sobre '0'/'1' es que con las operaciones + y
* es muy simple simular las operaciones booleanas.

> Y, last but no least, no se pueden definir índices con columnas tipo
> BIT.
>

Buen punto, aunque dada la poca selectividad de las columnas de tipo
booleana, suelen participar poco en indizaciones.

En resumen, me gusta más una representación numérica para un dato booleano.
Es una preferencia personal simplemente.

> Saludos,
> Carlos
>

Saludos,
~gux

Gustavo Larriera (MVP)

unread,
Sep 12, 2008, 8:56:11 PM9/12/08
to
Hola Carlos,

"Carlos M. Calvelo" wrote:

Los UDT no me agradan demasiado debido a que no permiten definir operaciones
sobre los valores del tipo. Por ejemplo, el AND, OR y NOT. En mi humilde
opinión, los UDT son una idea sin terminar :-)

En SQL Server 2005/2008 el poder definir tipos usando .NET es una mejora en
ese sentido. De todas formas no soy tampoco de definir tipos .NET para las
columnas, aunque tal vez para variables en los procedimientos.

> Saludos,
> Carlos
>

Saludos,
~gux

Carlos M. Calvelo

unread,
Sep 12, 2008, 9:04:52 PM9/12/08
to
Hola Gustavo,

On 13 sep, 02:45, Gustavo Larriera (MVP)


<GustavoLarriera...@discussions.microsoft.com> wrote:
>
> Lo que me gusta de usar 0/1 por sobre '0'/'1' es que con las operaciones + y
> * es muy simple simular las operaciones booleanas.
>

Ten cuidado de no hacer algo como
IF campo1 + campo2 = 1
en vez de
IF campo1 + campo2 > 0
:-)

Pero... buena idea.

Saludos,
Carlos

Carlos M. Calvelo

unread,
Sep 12, 2008, 10:34:03 PM9/12/08
to
Hola Gustavo,

On 13 sep, 02:56, Gustavo Larriera (MVP)


<GustavoLarriera...@discussions.microsoft.com> wrote:
> Hola Carlos,
>
> "Carlos M. Calvelo" wrote:
> > Ah!
> > Y crear un User defined type 'Boolean' con una restricción (rule)
> > y usar ese tipo consecuentemente a la hora de definir las tablas.
>
> > Por ejemplo 'Boolean' basado en char(5) y con una restricción
> > @value IN ('true', 'false')
>
> Los UDT no me agradan demasiado debido a que no permiten definir operaciones
> sobre los valores del tipo. Por ejemplo, el AND, OR y NOT. En mi humilde
> opinión, los UDT son una idea sin terminar :-)

:-)
Eso está claro. De 'tipos' no tienen nada. Son mas bien un alias de
tipos definidos por el sistema. Aun así, ofrecen la posibilidad de
especificar una restricción solo en un sitio en vez de en 100
columnas. O utilizando solo el nombre, se documenta que columnas en
distintas tablas son en realidad del mismo tipo (que tiene sentido
una comparacion de valores, por ejemplo.), aunque el tipo base sea
el mismo que en otras columnas que no tienen nada que ver.
Por ejemplo, decir que una columna es del tipo 'Temperatura' (INT)
nos dice que no tiene mucho sentido compararla con otra columna
del tipo Longitud (también INT)

>
> En SQL Server 2005/2008 el poder definir tipos usando .NET es una mejora en
> ese sentido. De todas formas no soy tampoco de definir tipos .NET para las
> columnas, aunque tal vez para variables en los procedimientos.
>

Uff... ese ya es un tema que se las trae. Bueno... por ahí es por
donde tenían que ir los UDT. Imagínate tener tipos como XMLDoc,
BITMAP, WordDocument, TextDocument, Foto, Map, Sound, etc, etc.

Y poder definirlos tu con las mismas posibilidades (definir
operadores) y con el mismo nivel de integración en el lenguaje que
los 'system defined types'.

Por poner un ejemplo muy sencillo:
A menudo tenemos la situación de que tenemos que definir rangos.
Algo como FechaInicial y FechaFinal. En estos casos estas dos
columnas son interdependientes ( ini <= fin). O sea que no dependen
solo de la clave. Si lo piensas bien, estas dos columnas a nivel de
lo que estamos definiendo en la tabla son una unidad y convendría
tener un tipo como Periodo.

Imagínate ahora poder definir un tipo Periodo, con esos dos
componentes y, entre otras cosas, operadores como Overlaps()...

WHERE tabla1.per.Overlaps(tabla2.per)

.. You get the idea!

Las propuestas de Date y Darwen son excelentes en este sentido y
siguen trabajando en el tema. Hasta con un buen modelo de herencia
de tipos.

Saludos,
Carlos

Maxi Accotto

unread,
Sep 15, 2008, 8:56:41 PM9/15/08
to
Bueno son formas nomas, yo a los usuarios no les muestro ni 1 ni 0 ni S ni
N, asi que es indistinto :) o tu le muestras 1 o 0? o bien los usas como
desarrollador y los interpretas luego? si usas bit a la larga tambien lo
tiene que convertir en algo que el usuario interprete jaja

Pero bueno son formas nomas!

--

Saludos
-----------------------------------------------------------------------
Maxi Accotto
Microsoft MVP en SQLServer
SQltotalconsulting
-------------------------------------------------------------------

"Gustavo Larriera (MVP)" <GustavoLa...@discussions.microsoft.com>

escribió en el mensaje de

noticias:5549D4FC-8DBD-449B...@microsoft.com...

agri...@gmail.com

unread,
Jul 20, 2018, 12:40:38 PM7/20/18
to
Saludos,

Sabes que tengo un campo de tipo Bit llamado Seleccion, pero el sistema me arroja el error: Incompatibilidad entre el operador y el tipo de operando. Método obtenerdata. El Profiler no reigistra nada y el código de ese procedimiento es el siguiente:

lcCo_prov = ALLTRIM(cProv.co_prov)
thisform.txtCodigo.Value = lcCo_prov
thisform.txtProveedor.Value = ALLTRIM(cProv.prov_des)

sql = "select tipo_doc," + ;
sql = sql + "nro_doc," + ;
sql = sql + "fec_emis," + ;
sql = sql + "fec_venc," + ;
sql = sql + "nro_fact," + ;
sql = sql + "observa," + ;
sql = sql + "monto_net," + ;
sql = sql + "saldo," + ;
sql = sql + "seleccion, " + ;
sql = sql + "co_cli " + ;
sql = sql + " from docum_cp" + ;
sql = sql + " where anulado = 0 and saldo > 0"
tresult = SQLEXEC(tconnect, sql, 'cTemp')
BROWSE
MESSAGEBOX(MESSAGE())


*sql = sql + "CONVERT(VARCHAR(10), fec_emis, 103) as fec_emis," + ;
*sql = sql + "CONVERT(VARCHAR(10), fec_venc, 103) as fec_venc," + ;

IF USED('cDocus')
DELETE FROM cDocus
INSERT INTO cDocus SELECT * FROM cTemp
ELSE
SELECT * FROM cTemp INTO CURSOR cDocus READWRITE
ENDIF

SELECT cDocus
SET FILTER TO alltrim(co_cli) == lcCo_prov
GO TOP
thisform.grid1.RecordSourceType = 1
thisform.grid1.RecordSource = 'cDocus'
thisform.grid1.Refresh

No encuentro la causa del error. Inicialmente le asignaba un valor cero a ese campo. Luego modifiqué la tabla creando el campo Seleccion de tipo Bit y finalmente cambié dos campos que estaban como tipo: smalldatetime a datetime; y aún sigue apareciendo el posible error.

Por favor podrías orientarme para resolver este asunto?
Te puedo enviar el Formulario completo para tu revisión si lo deseas, tan solo dame tu dirección de correo.

Muchas gracias!
0 new messages