Kod SQL oraz c# i błąd: "Msg 512 [...]"

0

Witam, mam problem z kodem SQL. Mianowicie mam za zadanie zorganizowanie kodu w sql i c#, który będzie pełnił następujące zadania:

Tworzę bazę danych (imię, nazwisko, pesel).
Przepuszczam kolejne numery pesel z bazy poprzez dll-ke wytworzoną przez kod programu w c# (kod jest raczej gotów i działa).

Wyświetlenie wyników:
*Wypisanie daty urodzenia, ilość dni do urodzin oraz płeć.
*Zaznaczenie która z osób jest najstarsza, poprzez osobne wypisanie jej imienia.

Problem z moim kodem zaczyna się kiedy muszę wypisać więcej niż jeden nr. pesel.
Wyrzuca wtedy błąd:
"Msg 512, Level 16, State 1, Line 14
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression."

Kody:

C#:

using System;
using System.Data;
using System.IO;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text;
using System.Globalization;

[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.UserDefined, MaxByteSize = 8000,
     IsByteOrdered = true, ValidationMethodName = "ValidatePesel")]

public struct Pesel : INullable, IBinarySerialize
{
    private bool is_Null;
    private string _s;
    public bool IsNull
    {
        get
        {
            return (is_Null);
        }
    }

    public static Pesel Null
    {
        get
        {
            Pesel p = new Pesel();
            p.is_Null = true;
            return p;
        }
    }

    // Use StringBuilder to provide string representation of UDT.
    public override string ToString()
    {
        if (this.IsNull)
            return "NULL";
        else
        {
            //Pesel p = new Pesel();
            return s.ToString();
        }
    }

    [SqlMethod(OnNullCall = false)]
    public static Pesel Parse(SqlString ss)
    {
        if (ss.IsNull)
        {
            return Null;
        }

        Pesel p = new Pesel();
        p.s = (string)ss;
        return p;
    }

    public string s
    {
        get
        {
            return this._s;
        }
        set
        {
            string temp = _s;
            _s = value;
            if (!ValidatePesel())
            {
                _s = temp;
                throw new ArgumentException("Invalid X coordinate value.");
            }
        }
    }

    public void Read(BinaryReader r)
    {
        _s = r.ReadString();
    }

    public void Write(BinaryWriter w)
    {
        string ss = _s.ToString();
        w.Write(ss);
    }

    public bool ValidatePesel()
    {
        int[] weights = { 1, 3, 7, 9, 1, 3, 7, 9, 1, 3 };
        bool result = false;
        if (_s.Length == 11)
        {
            int controlSum = CalculateControlSum(_s.ToString(), weights);
            int controlNum = controlSum % 10;
            controlNum = 10 - controlNum;
            if (controlNum == 10)
            {
                controlNum = 0;
            }
            int lastDigit = int.Parse(_s[_s.Length - 1].ToString());
            result = controlNum == lastDigit;
        }
        return result;
    }

    public static int CalculateControlSum(string input, int[] weights, int offset = 0)
    {
        int controlSum = 0;
        for (int i = 0; i < input.Length - 1; i++)
        {
            controlSum += weights[i + offset] * int.Parse(input[i].ToString());
        }
        return controlSum;
    }

    public string GetGender()
    {
        int temp = Int32.Parse(_s.Substring(10, 1));
        string plec;
        if (temp == 0 || temp == 2 || temp == 4 || temp == 6 || temp == 8)
        {
            plec = "plec: Kobieta";
        }
        else
        {
            plec = "plec: Mezczyzna";
        }

        return plec;


    }

    public string BirthDate()
    {
        if (ValidatePesel())
        {
            DateTime today = DateTime.Today;
            DateTime birthday = new DateTime(today.Year, Int32.Parse(_s.Substring(2, 2)), Int32.Parse(_s.Substring(4, 2)));
            DateTime next = new DateTime(today.Year, birthday.Month, birthday.Day);

            if (next < today)
                next = next.AddYears(1);

            int numDays = (next - today).Days;
            string birth = new SqlString("Dzien: " + _s.Substring(4, 2) + "Miesiąc: " + _s.Substring(2, 2) + "Rok: " + _s.Substring(0, 2) + "Dni_do_urodzin: " + numDays).ToString();
            return birth;
        }
        return null;

    }

}

SQL:

drop type Pesel
go
drop assembly pesel
go
create assembly pesel
authorization dbo
from 'C:\Users\Logan\Desktop\Projekt\Projekt.dll'
with permission_set = safe
go
create type dbo.Pesel
external name Pesel.Pesel
go
declare @a Pesel
set @a = (select numer_pesel AS pesel from dane)
select @a.ValidatePesel()
select @a.BirthDate()
select @a.GetGender()

Proszę o pomoc z naprawą kodu :)

PS:

Kiedy użyję kodu zawierającego tylko jeden nr pesel, wszystko jest OK. Przykład:

drop type Pesel
go
drop assembly pesel
go
create assembly pesel
authorization dbo
from 'C:\Users\Logan\Desktop\Projekt\Projekt.dll'
with permission_set = safe
go
create type dbo.Pesel
external name Pesel.Pesel
go
declare @a Pesel
set @a = cast('89051609796' AS pesel)
select @a.ValidatePesel()
select @a.BirthDate()
select @a.GetGender() 
0
reptile333 napisał(a):

Lektura poniższych powinna przynieść rozwiązanie
https://msdn.microsoft.com/en-us/library/ms131086.aspx#Anchor_1
https://msdn.microsoft.com/en-us/library/ms131086.aspx#Anchor_4

Próbowałem na wiele sposobów, ale nadal nie mogę osiągnać wyniku jakiego potrzebuję =/
SQL ewidentnie nie jest moją mocną stroną i ciężko mi zrobić coś z tym kodem =/

EDIT:
Udało mi się poczynić duży postęp, ale niestety również pojawił się nowy problem.
Posiadam kod, który w końcu wyrzuca odpowiednio wyniki. Ale teraz, chciałbym zmienić ten kod, aby wyniki zostały umieszczone w tabeli.

Kod na ten moment wygląda tak:

drop type Pesel
go
drop assembly pesel
go
create assembly pesel
authorization dbo
from 'C:\Users\Logan\Desktop\Projekt\Projekt.dll'
with permission_set = safe
go
create type dbo.Pesel
external name Pesel.Pesel
go
declare @a Pesel
select * from dbo.dane
declare @b int
set @b = 0
while @b < (select max(P_Id) from dane)
begin
set @a = (select numer_pesel as pesel from dane where P_Id = 1+@b) 
set @b += 1
if (select numer_pesel from dane) = null
break
select @a.ValidatePesel()
select @a.BirthDate() 
select @a.GetGender()
end

Próbowałem zastosować te metody:
http://www.sql-kursy.pl/t-sql-kurs-tworzenie-petli-while-w-t-sql-12.html

Ale albo robiłem to niezdarnie, albo nie zadziałały one w moim przypadku.
Proszę o nakierowanie mnie co dokładnie powinienem zrobić lub do czego konkretnie się odwołać przy pracy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1