[ASP/MSSQL2005] Varchar(max) returned semi-lege waarden

Pagina: 1
Acties:

  • steve2507
  • Registratie: Juli 2005
  • Laatst online: 10-10 17:19
Voor een nieuws site binnen het bedrijf waar ik werk, maak ik gebruik van ASP (JScript, niet .NET) & MSSQL2005 Express.
De body van een nieuws-item word daarbij opgeslagen in een varchar(max) veld.

Bij het ophalen van de waarde uit dit body veld, krijg ik nu niks in de browser te zien (maakt niet uit welke browser).

Google
Rond gezocht op google, en wat ik vooral terugvind is het bekende probleem waar velden als varchar(max) achteraan in de kolom selectie van je query moeten worden gedefiniëerd, maar dat was mij al bekend, dus dat doe ik ook.

Na enkele testen gedraaid, werd het probleem (voor mij) alleen maar raarder. Zie ook de testcase hieronder. De originele code is in JScript, maar de testcase heb ik voor het gemak in VBScript neergezet. Beiden hebben hetzelfde probleem.

Testcase
Aanmaken van de tabel & invoeren van één enkele waarde.
Connectionstring moet natuurlijk even worden aangepast indien iemand van plan is het zelf ook te testen.
Visual Basic:
1
2
3
4
5
6
7
8
9
10
 Dim Connection

 Set Connection=Server.CreateObject("ADODB.Connection")
 Connection.Open("driver={SQL Native Client};server=localhost;database=asa;uid=;pwd=;trusted_connection=yes;")

 Connection.Execute("create table test (body varchar(max))")

 Connection.Execute("insert into test (body) values ('dit is een test waarde met een length van 54 karakters')")

 Connection.Close()



Uitvoeren van de selectie, hier gebeuren rare dingen:
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 Dim b, Connection, rs

 Set Connection=Server.CreateObject("ADODB.Connection")
 Connection.Open("driver={SQL Native Client};server=localhost;database=asa;uid=;pwd=;trusted_connection=yes;")

 Set rs=Connection.Execute("select body from test")

 b=rs.Fields.Item("body").Value

 Response.Write("Value: ["&b&"]")
 Response.Write("<br />Length: "&Len(b)&"<br />Vartype: "&vartype(b)&"<br />Asc: "&Asc(Left(b,1)))

 rs.Close()
 Connection.Close()


Wanneer bovenstaande code word gedraaid, word de lengte correct weergegeven (54 karakters), de vartype is 8 (string).
Echter, bij de waarde, komt dit te staan:
code:
1
Value: [

Direct na de eerste bracket word de string afgekapt, de laatste bracket word niet naar het scherm geschreven.
Daarnaast levert de Asc '0' op. Ik ga er vanuit dat die 0 word gezien als het einde van de string, vandaar dat de Response.Write() er op dat moment mee ophoud.
De hele variable b staat daar overigens vol mee, maar waarom?

Wanneer ik de select-query in SQL Server Management Studio Express draai, dan geeft die de waarde wel correct weer.

Oplossing?
Een simpele oplossing voor bovenstaande testcase is de volgende select-query gebruiken, ipv de select die in de testcase is te vinden:
SQL:
1
select convert(text, body) as body from test

Echter, de originele query is een stuk ingewikkelder dan dat, en MSSQL staat het niet toe om dingen als 'distinct' te gebruiken icm 'text' velden, ook niet als er convert voor word gebruikt.

Een andere oplossing is gebruik maken van varchar(8000) ipv varchar(max). Dat doe ik nu ook, maar dat betekend wel dat ik aan een max van 8000 characters gebonden ben.
Op zich niet zo heel erg, ik hoor het wel wanneer men gaat zeuren dat het niet meer past ;-)
Er word gebruik gemaakt van een WYSIWYG editor, dus dat vult wel een stuk sneller dan plain text.

Toch ben ik benieuwd: heeft iemand enig idee hoe dit kan worden veroorzaakt? Ik heb veel mee gemaakt met ASP & verschillende database engines, maar dit slaat toch wel alles.
Het moge duidelijk zijn dat dit totaal geen tijdsnood of iets dergelijks heeft.

  • 4of9
  • Registratie: Maart 2000
  • Laatst online: 13-12-2024
Staan er rare tekens in je text? als dat zo is moet je nvarchar gebruiken (ivm met unicode chars).
Is body geen reserved word? zet body eens tussen brackets.

Je zegt dat er ingevoerd wordt dmv een WYSIWYG editor, dus staan er dan html tekens in je text?
Kijk eens in de source van de gegenereerde pagina, staat de text daar ook niet?
Heb je quotes geescaped?

Aspirant Got Pappa Lid | De toekomst is niet meer wat het geweest is...


  • steve2507
  • Registratie: Juli 2005
  • Laatst online: 10-10 17:19
4of9, gezien jouw reactie ga ik er even vanuit dat jij mijn post niet volledig hebt doorgelezen.

Daar kan je namelijk uit opmaken dat 'body' geen reserved word is en er geen problemen zijn met rare tekens (immers, in de management studio werkt het wel, en met een varchar(8000) veld, dan wel een convert(), ook in de browser)
Daarnaast kan je in de testcase zien dat ik geen gebruik maak van HTML tags om te testen.
En, zoals ik ook al had gemeld, levert Asc() voor elk karakter in de string een 0 op.
Als laatste: de test case maakt, zoals je kunt zien, geen gebruik van een WYSIWYG editor.

Verwijderd

Voor dit soort velden heeft MSSQL het type TEXT (blob subtype text bij andere databases). Je bent dan af van de beperking van max. 8192 karakters, en waarschijnlijk ook van die 0 karakters. Alleen indexeren (op full text search na) gaat niet op blobs, maar dat wil je ook niet.

  • steve2507
  • Registratie: Juli 2005
  • Laatst online: 10-10 17:19
Afterlife, wederom lijkt het erop dat niet mijn post in zijn geheel is doorgelezen.

Ik geef daarin tenslotte al aan dat ik het text veld niet kan gebruiken, omdat de query daar te ingewikkeld voor is. MSSQL staat het namelijk niet toe om dingen als group by, distinct ... te gebuiken icm blob velden.

Daarnaast is in MSSQL 2005 het varchar(max) veld geïntroduceerd om deze problemen met blob velden te voorkomen. Ook varchar(max) ondersteund, net als text, 2^31-1 karakters.
Microsoft geeft zelf zelfs aan om varchar(max) ed te gebruiken ipv text velden:
Important:
Use varchar(max), nvarchar(max), and varbinary(max) data types instead of text, ntext, and image data types.

  • pistole
  • Registratie: Juli 2000
  • Laatst online: 16:32

pistole

Frutter

Direct na de eerste bracket word de string afgekapt, de laatste bracket word niet naar het scherm geschreven.
Dat lijkt erop dat er een NULL staat in je veld. Wat is de output van onderstaande code?
Visual Basic:
1
Response.Write isnull(rs.Fields.Item("body").Value )

Ik frut, dus ik epibreer


  • steve2507
  • Registratie: Juli 2005
  • Laatst online: 10-10 17:19
pistole, in de testcase staat al aangegeven dat er wel degelijk een waarde bestaat, zie ook de insert query.

Bewijs daarvan is de lengte van de string, 54 karakters, deze geeft VBS ook netjes aan.
Daarnaast word de waarde wel teruggegeven als ik een convert over het veld in de query haal (zie oplossing?)
En, de management studio retourneert ook gewoon correct.

Dan nog, al zou het veld een null worden bevatten, dan hoort Response.Write() er niet plots mee te stoppen.

  • pistole
  • Registratie: Juli 2000
  • Laatst online: 16:32

pistole

Frutter

steve2507 schreef op zondag 31 december 2006 @ 13:04:
Bewijs daarvan is de lengte van de string, 54 karakters, deze geeft VBS ook netjes aan.
Daarnaast word de waarde wel teruggegeven als ik een convert over het veld in de query haal (zie oplossing?)
En, de management studio retourneert ook gewoon correct.
ik had over de convert heen gelezen. Wellicht dat de Native driver roet in het eten gooit. Wat gebeurt er als je driver={SQL Server} gebruikt?
Dan nog, al zou het veld een null worden bevatten, dan hoort Response.Write() er niet plots mee te stoppen.
Eens, maar ASP doet wel vaker dingetjes die niet horen (zie ook problemen dit kunnen onstaan met ADODB.Recordset als je text / memo velden gaat benaderen, hoewel ik niet weet of dat aan ADO of aan ASP ligt). Dat een NULL value een response.write "afkapt" is voor mij i.i.g. zeker...

* pistole programmeert al bijna 10 jr in ASP

Ik frut, dus ik epibreer


  • steve2507
  • Registratie: Juli 2005
  • Laatst online: 10-10 17:19
Kijk eens aan. Het wijzigen van de native driver naar sql server werkt inderdaad.
Ik moest daarvoor wel nog even de server van localhost naar de echte naam veranderen, want localhost vond ie niet leuk.

Over het null verhaal: VBScript schijft gewoon niks weg op de plaats van de null, met als resultaat dus:
code:
1
Value: []

JScript zou keihard 'null' tussen de brackets neerzetten.

In ieder geval bedankt!
Oplossing was toch eigenlijk iets te makkelijk om er zelf niet achter te zijn gekomen...
Pagina: 1