Avatar billede simsen Mester
17. september 2008 - 14:00 Der er 16 kommentarer og
1 løsning

SP - fejl ved indsættelse i decimal felt

Hej,

Jeg har en tabel, med en decimal felt, hvor Data Type er sat til decimal(18,2).

Forsøger jeg mig med en query (i management studio) med insert i kun det felt, sætter den korrekt 5308,40 ind
(INSERT INTO TtxVehicle (fFactoryFittedEquipmentPrice) VALUES(5308.40))
MEN forsøger jeg mig med at gøre det i min stored procedure - og executer sp'en i management studio - stjæler den slet og ret de 40 efter komma tallet......

Håber én af jer kan se, hvad der går galt - min sp ser således ud - det er (fFactoryFittedEquipmentPrice) den er galt med:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER PROCEDURE [dbo].[XNewFactoryFittedEquipment]
    @environment AS NVARCHAR(1) = null, --miljøtype
    @programtype AS NVARCHAR(1) = null, --programtype
    @vendorId AS INT = null, --ForhandlerId
    @fDimFId AS INT = null, --Køretøjs type (Vehicle, FactoryFittedEquipment, VendorFittedEquipment)
    @fCaseFId AS INT = null, --Sags ID
    @fModFId AS INT = null, --Model Id
    @fGrpEqFId AS INT = null, --Gruppe Equipment Id
    @fGrpEqPriFId AS INT = null, --Gruppe Equipment prislinie Id
    @fFactoryFittedEquipmentPrice AS DECIMAL = null --Fabriksmonteret udstyrs Pris

AS

BEGIN
    DECLARE @SQLString NVARCHAR(2500)
    DECLARE @XfDimFId VARCHAR(50)
    DECLARE @XfCaseFId VARCHAR(50)
    DECLARE @XfModFId VARCHAR(50)
    DECLARE @XfGrpEqFId VARCHAR(50)
    DECLARE @XfGrpEqPriFId VARCHAR(50)
    DECLARE @XfFactoryFittedEquipmentPrice VARCHAR(50)

    SET @XfDimFId= CONVERT(VARCHAR(50), @fDimFId)
    SET @XfCaseFId= CONVERT(VARCHAR(50), @fCaseFId)
    SET @XfModFId= CONVERT(VARCHAR(50), @fModFId)
    SET @XfGrpEqFId= CONVERT(VARCHAR(50), @fGrpEqFId)
    SET @XfGrpEqPriFId= CONVERT(VARCHAR(50), @fGrpEqPriFId)
    SET @XfFactoryFittedEquipmentPrice = CONVERT(VARCHAR(50), @fFactoryFittedEquipmentPrice)

    BEGIN TRANSACTION
        BEGIN TRY
            BEGIN
                SET @SQLString = 'INSERT INTO '
                SET @SQLString = @SQLString + @environment + 'txVehicle '
                SET @SQLString = @SQLString + '(fDimFId, fCaseFId, fModFId, fGrpEqFId, fGrpEqPriFId, fFactoryFittedEquipmentPrice)'
                SET @SQLString = @SQLString + 'VALUES (' + @XfDimFId + ',' + @XfCaseFId + ',' + @XfModFId + ',' + @XfGrpEqFId + ',' + @XfGrpEqPriFId + ',' + @XfFactoryFittedEquipmentPrice + ')'
                EXEC sp_executesql @SQLString
            END
            COMMIT TRANSACTION
        END TRY
        BEGIN CATCH
            ROLLBACK TRANSACTION
        END CATCH

END

mvh
simsen :-)
Avatar billede arne_v Ekspert
17. september 2008 - 14:08 #1
proev:

@fFactoryFittedEquipmentPrice AS DECIMAL(12,2) = null
Avatar billede simsen Mester
17. september 2008 - 14:24 #2
arne

Hejsa,

fandt jeg også lige ud af - håber du gider hjælpe mig.........fandt nemlig ud af at problemet for mig, er at jeg opretter de stored procedures igennem VS2008.......

Hvordan angiver jeg der de decimal(18,2).....

Når jeg laver min sp igennem VS - gør jeg følgende:

[Microsoft.SqlServer.Server.SqlProcedure]
    public static void NewFactoryFittedEquipment(string environment, string programtype, int vendorId, int fDimFId, int fCaseFId, int fModFId, int fGrpEqFId, int fGrpEqPriFId, decimal fFactoryFittedEquipmentPrice)
    {
        SqlConnection conn = new SqlConnection("Context Connection=true");
        SqlCommand cmd = new SqlCommand();

        cmd.Connection = conn;

        cmd.Parameters.Add(new SqlParameter("@environment", environment));
        cmd.Parameters.Add(new SqlParameter("@programtype", programtype));
        cmd.Parameters.Add(new SqlParameter("@vendorId", vendorId));
        cmd.Parameters.Add(new SqlParameter("@fDimFId", fDimFId));
        cmd.Parameters.Add(new SqlParameter("@fCaseFId", fCaseFId));
        cmd.Parameters.Add(new SqlParameter("@fModFId", fModFId));
        cmd.Parameters.Add(new SqlParameter("@fGrpEqFId", fGrpEqFId));
        cmd.Parameters.Add(new SqlParameter("@fGrpEqPriFId", fGrpEqPriFId));
        cmd.Parameters.Add(new SqlParameter("@fFactoryFittedEquipmentPrice", fFactoryFittedEquipmentPrice));

        cmd.CommandText = @"DECLARE @SQLString NVARCHAR(2500)
    DECLARE @XfDimFId VARCHAR(50)
    DECLARE @XfCaseFId VARCHAR(50)
    DECLARE @XfModFId VARCHAR(50)
    DECLARE @XfGrpEqFId VARCHAR(50)
    DECLARE @XfGrpEqPriFId VARCHAR(50)
    DECLARE @XfFactoryFittedEquipmentPrice VARCHAR(50)

    SET @XfDimFId= CONVERT(VARCHAR(50), @fDimFId)
    SET @XfCaseFId= CONVERT(VARCHAR(50), @fCaseFId)
    SET @XfModFId= CONVERT(VARCHAR(50), @fModFId)
    SET @XfGrpEqFId= CONVERT(VARCHAR(50), @fGrpEqFId)
    SET @XfGrpEqPriFId= CONVERT(VARCHAR(50), @fGrpEqPriFId)
    SET @XfFactoryFittedEquipmentPrice = CONVERT(VARCHAR(50), @fFactoryFittedEquipmentPrice)

    BEGIN TRANSACTION
        BEGIN TRY
            BEGIN
                SET @SQLString = 'INSERT INTO '
                SET @SQLString = @SQLString + @environment + 'txVehicle '
                SET @SQLString = @SQLString + '(fDimFId, fCaseFId, fModFId, fGrpEqFId, fGrpEqPriFId, fFactoryFittedEquipmentPrice)'
                SET @SQLString = @SQLString + 'VALUES (' + @XfDimFId + ',' + @XfCaseFId + ',' + @XfModFId + ',' + @XfGrpEqFId + ',' + @XfGrpEqPriFId + ',' + @XfFactoryFittedEquipmentPrice + ')'
                EXEC sp_executesql @SQLString
            END
            COMMIT TRANSACTION
        END TRY
        BEGIN CATCH
            ROLLBACK TRANSACTION
        END CATCH";

        conn.Open();

        SqlDataReader rdr = cmd.ExecuteReader();
        SqlContext.Pipe.Send(rdr);

        rdr.Close();
        conn.Close();
    }

Og jeg kan ikke se hvorhenne, jeg kan angive (18,2) henne?

mvh
simsen :-)
Avatar billede arne_v Ekspert
17. september 2008 - 15:41 #3
Linien kunne jo bare rettes i din oprindelige ALTER PROCEDURE.

Jeg kan slet ikke se meningen med din C# kode. Den kunne da bare laves med en banal SqlCommand.

Jeg tror ioevrigt slet ikke at den har 18,2 problemet - men skulle det tilfoejes saa
maa det vaere i:

cmd.Parameters.Add(new SqlParameter("@fFactoryFittedEquipmentPrice", fFactoryFittedEquipmentPrice));
Avatar billede simsen Mester
17. september 2008 - 15:55 #4
Hejsa arne,

Jeg har copy/pastet sql strengen over i min VS udgave og jeg har problemet lige netop der .......den hakker de 40 øre væk.....

Nu forstår jeg ikke hvad du mener med banal SqlCommand - hvis du mener hvorfor jeg sætter det ind i en streng - så er det fordi - vi taler om to forskellige tabeller - men samme kode.....(om det er produktion eller test)..... og jeg er doven - så gider ikke lave to sp'ere

cmd.Parameters.Add(new SqlParameter("@fFactoryFittedEquipmentPrice", fFactoryFittedEquipmentPrice));

Også der jeg har forsøgt mig med efterhånden mange forskellige måder..... men jeg får alverdens fejl, - hvor skal den nøjagtig stå og hvordan
decimal(18,2) - her får jeg at vide, den bliver brugt som metode......som fejl
decimal - her får jeg at vide invalid expression term
decimal[18,2] - her får jeg at vide invalid expression term

Håber du har en idé :-)
Avatar billede arne_v Ekspert
17. september 2008 - 16:54 #5
cmd.Parameters.Add(new SqlParameter("@fFactoryFittedEquipmentPrice", SqlDbType.Decimal));
cmd.Parameters["@fFactoryFittedEquipmentPrice"].Precision = 12;
cmd.Parameters["@fFactoryFittedEquipmentPrice"].Scale = 2;
cmd.Parameters["@fFactoryFittedEquipmentPrice"].Value = fFactoryFittedEquipmentPrice;

maa vaere en maade
Avatar billede arne_v Ekspert
17. september 2008 - 16:56 #6
Og saa ville jeg bare lave CommandText som en simpel INSERT !

Tabel navn som dynamisk SQL og vaerdierne som parameters.
Avatar billede simsen Mester
18. september 2008 - 08:16 #7
Hejsa arne,

Nu har jeg forsøgt mig med nedenstående (har skåret det væk, der ikke har betydning
Og den afrunder stadigvæk.......

Koden ser således ud:
[Microsoft.SqlServer.Server.SqlProcedure]
    public static void NewFactoryFittedEquipment(decimal fFactoryFittedEquipmentPrice)
    {
        SqlConnection conn = new SqlConnection("Context Connection=true");
        SqlCommand cmd = new SqlCommand();

        cmd.Connection = conn;
        cmd.Parameters.Add(new SqlParameter("@fFactoryFittedEquipmentPrice", SqlDbType.Decimal));
        cmd.Parameters["@fFactoryFittedEquipmentPrice"].Precision = 18;
        cmd.Parameters["@fFactoryFittedEquipmentPrice"].Scale = 2;
        cmd.Parameters["@fFactoryFittedEquipmentPrice"].Value = fFactoryFittedEquipmentPrice;

        cmd.CommandText = @"INSERT INTO TtxVehicle
                            (fFactoryFittedEquipmentPrice)
                            VALUES (@fFactoryFittedEquipmentPrice)";

        conn.Open();

        SqlDataReader rdr = cmd.ExecuteReader();
        SqlContext.Pipe.Send(rdr);

        rdr.Close();
        conn.Close();
    }

Hvad mener du med "Tabel navn som dynamisk SQL" og for at være helt sikker - så bruger jeg da værdierne som parameters?
Avatar billede Syska Mester
18. september 2008 - 08:40 #8
Ikke for at være selvfed ... men kan det ikke have noget at gøre med dansk/engelsk og at vi bruger forskellig 1000 seperator eller måske noget i den retning ? Lige hvad jeg kunne kommem fra morgenen.

// ouT
Avatar billede simsen Mester
18. september 2008 - 09:44 #9
buzzzz
Nej det er ikke problemet - hvis jeg kører den her kode igennem management studio og der definerer (12,8)........så går den fint igennem med 1535.45 - så det er noget af det arne er inde på - er jeg ikke i tvivl om.

Men tak for dit input :-)
Avatar billede arne_v Ekspert
18. september 2008 - 12:27 #10
buzzzz>

Naar foerst tallet er i en decimal og man bruger parameters, saa boer der ikke vaere
noget med komma & punktum som er en ren tekst ting.

simsen>

Hvilket naturligvis rejser spoergsmaalet: har du testet at din decimal indeholder
det rigtige tal med 2 decimaler ?
Avatar billede simsen Mester
18. september 2008 - 12:39 #11
arne
Det jeg helt nøjagtig gør, at først at oprette SP i VS og så deploy'e. Så går jeg i SQL Server Management Studio og executer den SP, jeg lige har oprettet og skriver i feltet: 15.54 - jeg checker så tabellen og ser, den har ændret det til 16,00

SP jeg deployer fra VS
[Microsoft.SqlServer.Server.SqlProcedure]
    public static void NewFactoryFittedEquipment(decimal fFactoryFittedEquipmentPrice)
    {
        SqlConnection conn = new SqlConnection("Context Connection=true");
        SqlCommand cmd = new SqlCommand();

        cmd.Connection = conn;
        cmd.Parameters.Add(new SqlParameter("@fFactoryFittedEquipmentPrice", SqlDbType.Decimal));
        cmd.Parameters["@fFactoryFittedEquipmentPrice"].Precision = 18;
        cmd.Parameters["@fFactoryFittedEquipmentPrice"].Scale = 2;
        cmd.Parameters["@fFactoryFittedEquipmentPrice"].Value = fFactoryFittedEquipmentPrice;

        cmd.CommandText = @"INSERT INTO TtxVehicle
                            (fFactoryFittedEquipmentPrice)
                            VALUES (@fFactoryFittedEquipmentPrice)";

        conn.Open();

        SqlDataReader rdr = cmd.ExecuteReader();
        SqlContext.Pipe.Send(rdr);

        rdr.Close();
        conn.Close();
    }


Så opretter jeg en ny SP men denne gang i Management Studio. Jeg executer SP'en og skriver i feltet 15.54. Jeg checker nu i tabellen og den har skrevet 15,54

SP opbygget i Management Studio:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

CREATE PROCEDURE [dbo].[XXTest]
    @fFactoryFittedEquipmentPrice AS DECIMAL(18,2) = null
AS
BEGIN
    BEGIN TRANSACTION
        BEGIN TRY
            BEGIN
                INSERT INTO TtxVehicle
                            (fFactoryFittedEquipmentPrice)
                            VALUES (@fFactoryFittedEquipmentPrice)
            END
            COMMIT TRANSACTION
        END TRY
        BEGIN CATCH
            ROLLBACK TRANSACTION
        END CATCH   
END

Det skal siges - uanset om jeg gør det den ene sted eller andet, så kan jeg IKKE skrive 15,54 - jeg skal bruge punktum (engelsk version)

Hvordan tester jeg om min decimal indeholder det rigtige tal med 2 decimaler?
Avatar billede simsen Mester
18. september 2008 - 12:41 #12
Og jeg HAR checket 127 gange, at feltet er et decimal(18,2) felt.....
Avatar billede simsen Mester
22. september 2008 - 13:34 #13
arne v

Smid og du får nogle points.

mvh
simsen :-)
Avatar billede Syska Mester
23. september 2008 - 09:47 #14
Betyder det at du fandt en løsning eller ?

// ouT
Avatar billede simsen Mester
23. september 2008 - 12:08 #15
buzzz
Nej det gjordet det ikke.........er stadig på bar bund hvorfor den gør det........ Forsøger at stille spørgsmålet ude i den store cyber verden istedet :-)
Avatar billede simsen Mester
24. september 2008 - 08:28 #16
Herre gud da........

Jeg har fundet løsningen.......selvom den i mine øjne er meget kringelkroget......

[Microsoft.SqlServer.Server.SqlProcedure]
    public static void Test(double fFactoryFittedEquipmentPrice)
    {
        SqlConnection conn = new SqlConnection("Context Connection=true");
        SqlCommand cmd = new SqlCommand();

        cmd.Connection = conn;
        cmd.Parameters.Add(new SqlParameter("@fFactoryFittedEquipmentPrice", SqlDbType.Decimal));
        cmd.Parameters["@fFactoryFittedEquipmentPrice"].Precision = 18;
        cmd.Parameters["@fFactoryFittedEquipmentPrice"].Scale = 2;
        cmd.Parameters["@fFactoryFittedEquipmentPrice"].Value = fFactoryFittedEquipmentPrice;

        cmd.CommandText = @"INSERT INTO TtxVehicle
                            (fFactoryFittedEquipmentPrice)
                            VALUES (@fFactoryFittedEquipmentPrice)";

        conn.Open();

        SqlDataReader rdr = cmd.ExecuteReader();
        SqlContext.Pipe.Send(rdr);

        rdr.Close();
        conn.Close();
    }

Altså jeg ændrede input parameteren til en double fra at være en decimal.......

I mine øjne en underlig måde at skulle gøre tingene på - man indtaster en double til et decimalfelt i databasen - som forøvrigt også erklæres som en decimal felt i stored proceduren.........
Avatar billede simsen Mester
19. november 2008 - 08:46 #17
arne v

Vil du have points for ovenstående, siger du bare til, så får du dem fluks :-)
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