20. februar 2010 - 16:44Der er
8 kommentarer og 1 løsning
SqlException: Error converting data type nvarchar to int.
Hej prøver at kalde en SqlServer stored procedure fra C#, men bliver mødt med en SqlException når jeg kalder ExecuteNonQuery() på mit SqlCommand object. Jeg har gået alle mine parametre igennem flere gange og må efterhånden erkende at jeg har set mig helt blind på hvad der forsager denne exception. Er der nogen der kan hjælpe?
######################################################## C# kode: ######################################################## public class PAccountGroups_GetById { public PAccountGroups_GetByIdResult ExecuteNonQuery(int @iAccountGoupsId, object transaction) { SqlConnection conn = null; SqlCommand cmd = null; try { conn = new SqlConnection(SqlConnectionString.ConnectionString); conn.Open(); cmd = conn.CreateCommand(); if (transaction != null) cmd.Transaction = (SqlTransaction)transaction; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "pAccountGroups_GetById";
public class PAccountGroups_GetByIdResult { public PAccountGroups_GetByIdResult() { OutputParameters = new PAccountGroups_GetByIdOutputParams(); } public PAccountGroups_GetByIdOutputParams OutputParameters { get; set; } }
public class PAccountGroups_GetByIdOutputParams { public int @oAccountType { get; set; } public string @oName { get; set; } public string @oDescription { get; set; } public int @oAccountGroupsId { get; set; } }
######################################################## SqlServer Stored Procedure ######################################################## /****** Object: StoredProcedure [dbo].[pAccountGroups_GetById] Script Date: 02/20/2010 16:29:32 ******/ SET ANSI_NULLS ON GO
SET QUOTED_IDENTIFIER OFF GO
CREATE PROCEDURE [dbo].[pAccountGroups_GetById] @iAccountGoupsId INT, @oAccountType INT OUT, @oName NVARCHAR(255) OUT, @oDescription NVARCHAR(4000) OUT, @oAccountGroupsId INT OUT AS BEGIN SET NOCOUNT ON;
BEGIN TRY
SELECT @oAccountGroupsId = AccountGroupsId, @oAccountType = AccountType, @oDescription = [Description], @oName = Name FROM tAccountGroups WHERE AccountGroupsId = @iAccountGoupsId
IF @oAccountGroupsId IS NULL BEGIN RAISERROR ('The AccountGroup could not be found.',18,1) END
Ja, datatyperne i de kolonner der bliver selected er af samme type og størrelse som procedures parametre. God pointe med varchar længde. Jeg havde set at der var en overloaded constructor af SqlParamterer hvor dette kunne angives.
Janus ->
Hvad mener du når du siger det ikke den bedste måde at hente data ud på? Er det fordi du mener at det performer dårligt? Det er ikke et krav jeg har fået stillet, men måden jeg selv har valgt. Jeg har på det sidste gjort stort brug af stored procedures, og er derfor i gang med at skrive en applikation der kan generere den nødvendige C# kode til at kalde disse. Ovenstående C# klasser er genereret på baggrund af proceduren, men som det fremgår af denne tråd er det ikke kørende endnu.. :s
Man kan lægge sin logik 2 steder, enten i applikationen eller på db-niveau vha. sprocs. Problemet med sprocs er ofte at de bliver misbrugt til selects hvor den ene parameter skal tweakes og der skal være flere sprocs til samme udtryk med med et variabelt antal parameters; langtfra optimalt imho. Misforstå mig ikke, jeg synes sprocs er geniale (tjek min profil :) ) og jeg ville absolut ikke undvære dem, men alt med måde!
Som du selv sidder nu, med problemer omkring parameters, så forestil dig problemstillingen igen hvis / når sproc'en skal ændres lidt. Hvis jeg lige skal bedømme din kode, så er din sproc måske lige for overgjort/ besværliggjort. Du binder forretningslogik op på account group, en check som kunne være gjort i dit data access lag, hvad nu hvis account typen heller ikke kunne findes osv. osv. Det er muligt det ikke er sådan lige nu, men som vi alle ved i udvikling, så har tingene det med at ehhmm "udvikle" sig :) Og så skal du rette dels din sproc men også din applikation, igen ikke videre optimalt. Derudover har du noget try-catch som umiddelbart ikke giver mening, kan være det senere skal udvides, men igen... forretningslogikken forplumrer renheden i sproc'en.
Mht. performance, så performer en sproc nu ikke nødvendigvis bedre en ren Sql, i enkelte tilfælde snarere tværtimod.
Selve C# koden bruger du også tid på at skrive og debugge, jeg går udfra du har et datalag, så når du modtager et resultat fra sproc'en skal du ligeledes mappe det videre, ofte 1 til 1. Når du arbejder med datalag er der ingen grund til at anvende sproc's, så er du bedre tjent med bare at skrive sql'en direkte i dal'en og så evt. hvis du ønsker en abstraktion til dine tabeller så opretter du views og bruger dem i din Sql istedet for at refererer direkte til tabellen. Ligeledes vil det også gøre en evt. deploy meget nemmere, da man ikke er afhængig af 300 små sprocs på db'en.
Alt i alt ville man have opnået en mere forståelig og mere vedligeholdelsesvenlig kode som ville fylde 5-6 linjer istedet.
Jeg har selv været stormisbruger af sprocs, min opfattelse har dog ændret sig efter mange års filosofering over hvorfor vi gør som vi gør - er det i virkeligheden bare fordi "sådan plejer man..."
Nu er der så kommet Linq to Sql / Entities, hvilket kun gør det hele endnu nemmere, da du totalt undgår dine casts og iterationer, men det er en anden snak :)
I forbindelse med at jeg har foretaget andre ændringer er dette problem forsvundet. Jeg gider ikke bruge kræfter på at genskabe det, så jeg lukker spørgsmålet.
Tak for jeres tid. Og tak fordi du ville dele dine holdninger med mig Janus. Det vil jeg tage til eftertanke.
Det ville jeg også mene. Jeg troede dog at normen herinde var anderledes, da min erfaring siger at folk takker nej, såvidt de ikke har besvaret det spørgsmål der var oprettet.
Men jeg giver gerne points for folks tid. Men kan jeg så genindsætte points på dette spørgsmål, eller skal jeg starte et nyt? Og vil det i så fald ikke være dårlig skik? Altså at "spamme" eksperten med ikke-fagrelevante spørgsmål...
Synes godt om
Ny brugerNybegynder
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.