Avatar billede csvendsen Nybegynder
05. maj 2012 - 05:58 Der er 11 kommentarer og
2 løsninger

MS-SQL database

Jeg har lavet følgende Stored Procedure i MS-SQL men får fejl når parameteren @col = 'Bemærkning'

Når der sorteres på alle andre kolonner fungerer det fint.

Kolonnen 'Bemærkning' findes i tabellen 'HøjbedTemperatur'

Fejlmeldingen når jeg laver en execute på SQL Serveren:

Msg 241, Level 16, State 1, Procedure spGetHøjbedTemperatur, Line 7
Conversion failed when converting date and/or time from character string.

Er der nogen som kan hjælpe, har forsøgt at ændre kolonnenavnet fra Bemærkning til Bemaerkning
men det er ikke det danske tegn som er årsagen.


USE [csdat49_database]
GO
/****** Object:  StoredProcedure [dbo].[spGetHøjbedTemperatur]    Script Date: 05/05/2012 05:04:03 ******/
SET ANSI_NULLS ON
GO
ALTER PROCEDURE [dbo].[spGetHøjbedTemperatur]
  @col varchar(25),
  @dir varchar(4)
AS
BEGIN
    SET NOCOUNT ON;
    Select convert(varchar(10),[Dato],105) as Dato, Inde_Temp, Jord_Temp,
    Ude_Temp, Bemærkning from HøjbedTemperatur
    order by 
        CASE @dir
            WHEN 'desc' THEN 
            CASE @col
                WHEN 'Dato' THEN [Dato]
                WHEN 'Inde_Temp' THEN [Inde_Temp]
                WHEN 'Jord_Temp' THEN [Jord_Temp]
                WHEN 'Ude_Temp' THEN [Ude_Temp]
                WHEN 'Bemærkning' THEN [Bemærkning]
                END
            END
            DESC,
        CASE @dir
            WHEN 'asc' THEN 
            CASE @col
                WHEN 'Dato' THEN  [Dato]
                WHEN 'Inde_Temp' THEN [Inde_Temp]
                WHEN 'Jord_Temp' THEN [Jord_Temp]
                WHEN 'Ude_Temp' THEN [Ude_Temp]
                WHEN 'Bemærkning' THEN [Bemærkning]
                END
            END
            ASC
END
Avatar billede mireigi Novice
05. maj 2012 - 13:14 #1
Det var da en besværlig måde at gøre det på :)

Dette kan gøre præcis det samme:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spGetHoejbedTemperatur]
    @col varchar(25),
    @dir varchar(4),
    @debug bit = 0
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @SQL nvarchar(max)
    DECLARE @br nvarchar(2)
    SET @br = CHAR(13)+CHAR(10)

    SET @SQL =    'SELECT' + @br +
                '    CONVERT(varchar(10),' + @br +
                '    [Dato],105) as Dato,' + @br +
                '    Inde_Temp,' + @br +
                '    Jord_Temp,' + @br +
                '    Ude_Temp,' + @br +
                '    Bemaerkning' + @br +
                'FROM' + @br +
                '    HoejbedTemperatur' + @br +
                'ORDER BY' + @br +
                '    ' +    @col + ' ' + @dir + ';'
   
    IF @debug = 0
        EXEC sp_ExecuteSQL @SQL
    ELSE
        PRINT @SQL
END
GO


Læg mærke til, at jeg har erstattet æ, ø og å med ae, oe og aa. Det er generelt en god ide at holde sig væk fra specialtegn, hvilket æøå hører ind under.

Stored Proceduren kan kaldes uden at angive @debug, hvor denne så defaulter til 0, og SQL'en eksekveres normalt. Den er der udelukkende for netop at kunne debugge den dynamiske SQL.
Avatar billede arne_v Ekspert
05. maj 2012 - 17:28 #2
Jeg ville undgaa sp_ExecuteSQL medmindre det var meget noedvendigt.

Ikke p.g.a. performance (den cacher query planer ligesom alt muligt andet).

Men det goer det faktisk muligt at faa et SQL injection problem i en SP.

Og det kan goere det vanskeligere at troubleshoot kodn.
Avatar billede janus_007 Nybegynder
05. maj 2012 - 17:32 #3
Her ses et tydeligt eksempel på hvorfor man IKKE skal bruge sprocs til simple dataudtræk :)

Hvis du stadig insisterer på at bruge en sproc, så udfør din "order by" i koden istedet.

Jeg er enig med mireigi om at man skal holde sig væk fra specialtegn, både når det kommer til navngivning af objekter og dels navngivning af kolonner.
Avatar billede ramad Praktikant
05. maj 2012 - 20:36 #4
Enig med arne_v i at du skal holde dig langt væk fra sp_ExecuteSQL. Så er der åbnet for ubehagelige ting som f.eks. "; DELETE FROM table".

Når det er sagt, så ville jeg høre om der er forskel på Dato i Bemærkning i forhold til i de andre tilfælde.
Avatar billede csvendsen Nybegynder
06. maj 2012 - 05:12 #5
Jeg har i første omgang prøvet med kommentar #1 fra
mireigi, dog uden at ændre æ og ø for lige at teste, og det var: 

SET @br = CHAR(13)+CHAR(10)

som skulle til. Nu fungerer det.

Tak for kommentarer fra i andre, og ja det er nok en god ide at undgå danske tegn i tabeller og kolonner.

Jeg troede at det altid var en fordel at benytte stored procedure for at forespørgsler udføres direkte på sql serveren.

Smid et svar og få velfortjente point.
Avatar billede janus_007 Nybegynder
07. maj 2012 - 17:11 #6
Anvendelsen af stored procedures skal begrænses når man har meget dynamiske/ variende sortering og filtrerings muligheder.

Når man er ude i sådan noget som du er her, og ligeledes når man ser dynamisk sql (set @sql = '....', #1 som du mente var korrekt), så er man 100% sikkert i gang med at dreje konceptet med stored procedures en smule for meget og det bør undgåes når man har mulighed for noget andet.

Et sted hvor en dynamisk stored procedure kan være anvendelig er hvis den skal afvikles igennem et sql-job hvor man ikke har mange andre muligheder.
Avatar billede csvendsen Nybegynder
08. maj 2012 - 04:09 #7
Så er jeg blevet lidt klogere mht. sp.

mireigi, ligger du et svar så du kan få point og jeg kan lukke spørgsmålet.
Avatar billede arne_v Ekspert
13. maj 2012 - 02:46 #8
Nej - man boer ikke altid bruge SP.

Men der er nogen tilfaelde, hvor det giver god mening.

Citat af mig selv fra anden traad:


Der er stadig visse gode grunde til at bruge SP:
- der er maalbare performance forbedringer hvis SP udfoerer flere SQL saetninger p.g.a de faerre roundtrips mellem app og database
- logik i SP's kan bruges fra forskelleige teknologier d.v.a. at man kan udnytte dem fra C#, Java og COBOL
- de kan forbedre database sikkerheden, da en SP kan have adgang til data som det brugte brugernavn ikke har adgang til
- de kan fungere som et public API for databasen som database arkitekter og DBA kan bruge til at aendre i databasen uden at paavirke apps

(generelt vil jeg dog stadig fraaraade brug af SP, da de goer det uhyggeligt dyrt at skifte database leverandoer)
Avatar billede csvendsen Nybegynder
20. maj 2012 - 06:41 #9
Jeg opdagede at sortering på Dato ikke virkede, de øvrige kolonner sorterer korrekt.
Ved at tilføje '_' i as Dato sorterer den korrekt på alle kolonner. Der er nok en logisk forklaring på det.

'SELECT' + @br +
                '    CONVERT(varchar(10),' + @br +
                '    [Dato],105) as Dato_,' + @br +....


mireigi, er du sød at smide et svar så jeg kan lukke spørgsmålet.
Glad for at jeg fik fidusen med at anvende 
SET @br = CHAR(13)+CHAR(10) og
IF @debug = 0
        EXEC sp_ExecuteSQL @SQL
    ELSE
        PRINT @SQL
Avatar billede csvendsen Nybegynder
21. maj 2012 - 06:54 #10
Så fandt jeg ud af hvorfor den ikke sorterer korrekt på dato kolonnen.
Den sorterer jo Dato som en streng.

Her er hvad der skal til for at sortere dato feltet korrekt:

strSQL = "SELECT  Convert(varchar(10),[Dato],105) as Dato,Inde_Temp,Jord_Temp, Ude_Temp, Bemærkning FROM HøjbedTemperatur ORDER BY "
      strSQL += " cast(Dato as DATETIME) " + sSortDirection
Avatar billede csvendsen Nybegynder
04. juni 2012 - 05:44 #11
Jeg mangler stadig svar fra mireigi.
Vil en af I andre som har skrevet kommentarer ligge et svar, så jeg kan lukke.
Avatar billede csvendsen Nybegynder
19. juni 2012 - 04:30 #12
Da ingen har svaret endnu må jeg vist selv svare.
Avatar billede csvendsen Nybegynder
19. juni 2012 - 04:30 #13
Lukker.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester