Gå til innhold

Anbefalte innlegg

Har et meget irriterende problem med SqlDataReader. Readeren returnerer i de fleste tilfellene det den skal, men iblant returnerer den ingenting, dette på tross av at spørringen returnerer noe i SQL Management Studio.

 

string findDefaultName = "SELECT sysObj.name FROM sysobjects AS sysObj JOIN syscolumns AS sysCol ON sysobj.id = sysCol.cdefault WHERE sysCol.name = '" + columnInformationList[0] + "' AND sysObj.parent_obj = (SELECT id FROM sysobjects WHERE name = '" + table[0] + "');";

SqlCommand findDefaultNameCommand = new SqlCommand(findDefaultName, thisDatabase3);

SqlDataReader myReader = findDefaultNameCommand.ExecuteReader();
while (myReader.Read())
{
  result = myReader["name"].ToString();
}
myReader.Close();

 

SELECT sysObj.name FROM sysobjects AS sysObj JOIN syscolumns AS sysCol ON sysobj.id = sysCol.cdefault WHERE sysCol.name = 'Enhet' AND sysObj.parent_obj = (SELECT id FROM sysobjects WHERE name = 'Vare');

 

Er et eksempel på en spørring som returnerer;

DF__Vare__Enhet__4924D839

i management studio, men ingenting i koden.

 

SELECT sysObj.name FROM sysobjects AS sysObj JOIN syscolumns AS sysCol ON sysobj.id = sysCol.cdefault WHERE sysCol.name = 'Feil' AND sysObj.parent_obj = (SELECT id FROM sysobjects WHERE name = 'KlientDI');

 

Returnerer derimot;

DF__KlientDI__Feil__1E6F845E

både i koden, samt i management studio.

 

Er det noen som har peiling på hvorfor den plutselig ikke returnerer noe?

 

Kan legge til at det alltid er de samme spørringene som ikke returnerer noe.

 

Mvh

 

Francis

Endret av :Francis:
Lenke til kommentar
Videoannonse
Annonse

1) FY!! Ikke konkatener tekststrenger! SQL insertion er ikke bra! Bruk

sysCol.name = @columnInformationListField AND sysObj.parent_obj = (SELECT id FROM sysobjects WHERE name = @tableField);

..og findDefaultNameCommand.AddWithValue("@columnInformationListField", columnInformationList[0]); findDefaultNameCommand.AddWithValue("@tableField", table[0]);

 

2) Finnes det en kolonne "name"? Prøv en av disse:

- SELECT sysObj.name AS name FROM..

- result = myReader["sysObj.name"].ToString();

- result = myReader[0].ToString();

Endret av Trondster
Lenke til kommentar

Takk for (raskt!) svar!

 

result = myReader[0].ToString();

 

Returnerer også ingenting en gang i blant, men det er også de samme spørringene som skjærer seg hver gang (får ikke feilmelding, bare ingenting ut).

 

result = myReader["sysObj.name"].ToString();

 

Gir IndexOutOfRangeException når det kjøres.

 

-

 

Parametere i SQL spørringene er nok viktig som du sier, men det har vel ikke noe med selve funksjonen å gjøre, kun sikkerhet mtp injection?

 

Mvh

 

Francis :)

Endret av :Francis:
Lenke til kommentar

Har ennå ikke fått det til å fungere, men har forsøkt å bruke parametere slik Trondster foreslo.

 

SqlCommand findDefaultNameCommand = new SqlCommand("SELECT sysObj.name FROM sysobjects AS sysObj JOIN syscolumns AS sysCol ON sysobj.id = sysCol.cdefault WHERE sysCol.name = '@columnInformationListField' AND sysObj.parent_obj = (SELECT id FROM sysobjects WHERE name = '@tableField');", thisDatabase3);

findDefaultNameCommand.Parameters.AddWithValue("@columnInformationListField", columnInformationList[0]);
findDefaultNameCommand.Parameters.AddWithValue("@tableField", table[0]);

SqlDataReader myReader = findDefaultNameCommand.ExecuteReader();
while (myReader.Read())
{
 result = myReader[0].ToString();
}
myReader.Close();

 

Det virker ikke som om parameterne blir registrert ettersom result er null hver gang.

 

Francis :)

Lenke til kommentar

Fikk ikke til å få returnert alle dataene fra databasen, slik at jeg skal løse det ved å gjøre logikken i en og samme spørring. Har sittet i management studio og kommet frem til dette:

 

DECLARE @defaultName varchar(100)
SET @defaultName = (SELECT sysObj.name FROM sysobjects AS sysObj JOIN syscolumns AS sysCol ON sysobj.id = sysCol.cdefault WHERE sysCol.name = 'test' AND sysObj.parent_obj = (SELECT id FROM sysobjects WHERE name = 'Alarmliste'))

IF @defaultName IS NOT NULL
BEGIN
EXEC('ALTER TABLE Alarmliste DROP CONSTRAINT ' + @defaultName)
END

ALTER TABLE [Alarmliste] ADD DEFAULT (0) FOR [test]

 

T-SQL er ganske kule saker IMO :)

 

Francis

Endret av :Francis:
Lenke til kommentar
Har ennå ikke fått det til å fungere, men har forsøkt å bruke parametere slik Trondster foreslo.

 

SqlCommand findDefaultNameCommand = new SqlCommand("SELECT sysObj.name FROM sysobjects AS sysObj JOIN syscolumns AS sysCol ON sysobj.id = sysCol.cdefault WHERE sysCol.name = '@columnInformationListField' AND sysObj.parent_obj = (SELECT id FROM sysobjects WHERE name = '@tableField');", thisDatabase3);

Ahem - fjern quotes rundt @parameternavn:

 

SELECT sysObj.name FROM sysobjects AS sysObj JOIN syscolumns AS sysCol ON sysobj.id = sysCol.cdefault WHERE sysCol.name = @columnInformationListField AND sysObj.parent_obj = (SELECT id FROM sysobjects WHERE name = @tableField);

 

..Dette ordner MSSQL for deg. :)

Lenke til kommentar

Takk, det gjorde susen å fjerne fnuttene.

 

Nå har jeg et litt annet problem:

 

SqlCommand defaultCommand = new SqlCommand("DECLARE @defaultName varchar(100) SET @defaultName = (SELECT sysObj.name FROM sysobjects AS sysObj JOIN syscolumns AS sysCol ON sysobj.id = sysCol.cdefault WHERE sysCol.name = @tableParam AND sysObj.parent_obj = (SELECT id FROM sysobjects WHERE name = @columnParam)) 

IF @defaultName IS NOT NULL 
BEGIN 
EXEC('ALTER TABLE [@tableParam] DROP CONSTRAINT ' + @defaultName) 
END 
ALTER TABLE [@tableParam] ADD DEFAULT (@defaultParam) FOR [@columnParam]", thisDatabase3);

defaultCommand.Parameters.AddWithValue("@tableParam", columnInformationList[0]);
defaultCommand.Parameters.AddWithValue("@columnParam", table[0]);
defaultCommand.Parameters.AddWithValue("@defaultParam", columnInformationList[columnInformationList.Count - 1]);

 

Jeg prøver å bruke parametere til dette, men får feilmeldingen:

 

Variables are not allowed in the ALTER TABLE statement.

 

Kan man ikke bruke @ parametere i ALTER delen av en spørring?

 

Francis

Lenke til kommentar

Du bør generelt ikke bruke ALTER TABLE og DROP CONSTRAINT i vanlige spørringer - det er som regel et hint om at du ikke gjør ting på den helt optimale måten. Eneste er hvis dette er noe engangs programmatisk endring av databasen. Hvis ikke: "FY!". ;)

 

Og nei, det kan man ikke. Tabellnavn, kolonnenavn og denslags kan ikke være variabler. Her skal du i så fall lage dynamisk sql og f.eks. kjøre EXEC på det du har konkatenert sammen.

For å escape her kan du bruke QUOTENAME. Tipper du kan kjøre noe a la:

EXEC('ALTER TABLE ' + QUOTENAME(@tableParam) + ' DROP CONSTRAINT ' + QUOTENAME (@defaultName))

Lenke til kommentar

Hva skulle nyutdannede som meg gjøre uten guruer som deg ;)?!

 

Dette er en engangs endring av databasen.

 

Jeg går i management studio, generer script med create spørringer for alle tabellene.

 

Kjører hele skriptet for å legge til tabeller som mangler og bruker "IF NOT EXISTS" for å unngå konflikter pga duplisering av tabeller.

 

Parser tekstfila som inneholder alle spørringene og legger til, endrer datatype og nullable etc. på den eksisterende databasen ut ifra strukturen på den nye som er definert i spørringene.

 

Håper ikke det finnes en kjempe enkel måte å oppdatere en gammel database til strukturen til den nye uten å droppe tabeller og kolonner, for da har jeg brukt myyyye tid forgjeves ;).

 

Applikasjonen skal være så lett at folk som knapt vet hva en database er for noe skal kunne gjøre oppdateringen fra gammel --> ny database.

 

Applikasjonen sletter ingenting, så eventuelle tabeller og kolonner som skal slettes må gjøres manuelt, men det forekommer svært sjeldent.

 

Francis

Endret av :Francis:
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...