Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Перевести код с 2005 на 2000 - го  [new]
Joris
Member

Откуда:
Сообщений: 186
Привет Всем!!!!
Ребята можете перевести этот код для SQL SERVER 2000, есть куче пример функция вычисление возраста в сайте, два три примера проверил все равно где то неправильно подсчитает., если можете помогите пожалуйста очень нужен……….

А теперь парочка функций для MS SQL 2005 на эту-же тему. 

[syntax="vb"]Imports System 
Imports System.Data 
Imports System.Data.SqlClient 
Imports System.Data.SqlTypes 
Imports Microsoft.SqlServer.Server 

Partial Public Class UserDefinedFunctions 
<Microsoft.SqlServer.Server.SqlFunction()> _ 
Public Shared Function ufnGetAgo(ByVal d1 As Date, ByVal d2 As Date, _ 
ByVal RetValue As Char, _ 
Optional ByVal RetValues As String = "YMDHNS" _ 
) As SqlInt32 
Dim Years As Integer, Months As Integer, Weeks As Integer, Days As Integer, Hours As Integer, Minutes As Integer, Seconds As Integer 
Dim dm As Date, dw As Date, dd As Date, dh As Date, dn As Date, ds As Date 

RetValue = UCase(RetValue) 
RetValues = UCase(RetValues) 
If RetValues.IndexOf(RetValue) < 0 Then Return New SqlInt32() 

If RetValues.IndexOf("Y") < 0 Then 
dm = d1 
If RetValue = "Y" Then Return New SqlInt32() 
Else 
Years = CInt(DateDiff(DateInterval.Year, d1, d2)) 
dm = DateAdd(DateInterval.Year, Years, d1) 
If dm > d2 Then 
Years -= 1 
dm = DateAdd(DateInterval.Year, Years, d1) 
End If 
End If 
If RetValue = "Y" Then Return New SqlInt32(Years) 

If RetValues.IndexOf("M") < 0 Then 
dw = dm 
If RetValue = "M" Then Return New SqlInt32() 
Else 
Months = CInt(DateDiff(DateInterval.Month, dm, d2)) 
dw = DateAdd(DateInterval.Month, Months, dm) 
If dw > d2 Then 
Months -= 1 
dw = DateAdd(DateInterval.Month, Months, dm) 
End If 
End If 
If RetValue = "M" Then Return New SqlInt32(Months) 

If RetValues.IndexOf("W") < 0 Then 
dd = dw 
If RetValue = "W" Then Return New SqlInt32() 
Else 
Weeks = CInt(DateDiff(DateInterval.Weekday, dw, d2)) 
dd = DateAdd(DateInterval.Weekday, Weeks, dw) 
If dd > d2 Then 
Weeks -= 1 
dd = DateAdd(DateInterval.Weekday, Weeks, dw) 
End If 
End If 
If RetValue = "W" Then Return New SqlInt32(Weeks) 

If RetValues.IndexOf("D") < 0 Then 
dh = dd 
If RetValue = "D" Then Return New SqlInt32() 
Else 
Days = CInt(DateDiff(DateInterval.Day, dd, d2)) 
dh = DateAdd(DateInterval.Day, Days, dd) 
If dh > d2 Then 
Days -= 1 
dh = DateAdd(DateInterval.Day, Days, dd) 
End If 
End If 
If RetValue = "D" Then Return New SqlInt32(Days) 

If RetValues.IndexOf("H") < 0 Then 
dn = dh 
If RetValue = "H" Then Return New SqlInt32() 
Else 
Hours = CInt(DateDiff(DateInterval.Hour, dh, d2)) 
dn = DateAdd(DateInterval.Hour, Hours, dh) 
If dn > d2 Then 
Hours -= 1 
dn = DateAdd(DateInterval.Hour, Hours, dh) 
End If 
End If 
If RetValue = "H" Then Return New SqlInt32(Hours) 

If RetValues.IndexOf("N") < 0 Then 
ds = dn 
If RetValue = "N" Then Return New SqlInt32() 
Else 
Minutes = CInt(DateDiff(DateInterval.Minute, dn, d2)) 
ds = DateAdd(DateInterval.Minute, Minutes, dn) 
If ds > d2 Then 
Minutes -= 1 
ds = DateAdd(DateInterval.Minute, Minutes, dn) 
End If 
End If 
If RetValue = "N" Then Return New SqlInt32(Minutes) 

If Seconds = 0 Then 
Return New SqlInt32() 
Else 
Seconds = CInt(DateDiff(DateInterval.Second, ds, d2)) 
End If 
If RetValue = "S" Then Return New SqlInt32(Minutes) 
End Function 

<Microsoft.SqlServer.Server.SqlFunction()> _ 
Public Shared Function ufnGetAgoString(ByVal d1 As Date, ByVal d2 As Date, _ 
Optional ByVal RetValues As String = "YMDHNS" _ 
) As SqlString 

Const sr As String = ", " 
Dim Years As Integer, Months As Integer, Weeks As Integer, Days As Integer, Hours As Integer, Minutes As Integer, Seconds As Integer 
Dim dm As Date, dw As Date, dd As Date, dh As Date, dn As Date, ds As Date 
Dim ss As String, s0 As String = vbNullString, sb As New System.Text.StringBuilder 

RetValues = RetValues.ToUpper 
If RetValues.Length = 0 Then Return New SqlString() 

If RetValues.IndexOf("Y") < 0 Then 
dm = d1 
Else 
Years = CInt(DateDiff(DateInterval.Year, d1, d2)) 
dm = DateAdd(DateInterval.Year, Years, d1) 
If dm > d2 Then 
Years -= 1 
dm = DateAdd(DateInterval.Year, Years, d1) 
End If 
If Years > 0 Then 
ss = Right(Years.ToString, 2) 
If ss.EndsWith("0") Or ss.StartsWith("1") Or CInt(Right(ss, 1)) >= 5 Then 
sb.Append(Years.ToString & " лет") 
Else 
sb.Append(Years.ToString & " год") 
If Not ss.EndsWith("1") Then sb.Append("а") 
End If 
Else 
s0 = "лет" 
End If 
End If 

If RetValues.IndexOf("M") < 0 Then 
dw = dm 
Else 
Months = CInt(DateDiff(DateInterval.Month, dm, d2)) 
dw = DateAdd(DateInterval.Month, Months, dm) 
If dw > d2 Then 
Months -= 1 
dw = DateAdd(DateInterval.Month, Months, dm) 
End If 
If Months > 0 Then 
ss = Right((100 + Months).ToString, 2) 
If sb.Length > 0 Then sb.Append(sr) 
sb.Append(Months.ToString & " месяц") 
If ss.EndsWith("0") Or ss.StartsWith("1") Or CInt(Right(ss, 1)) >= 5 Then 
sb.Append("ев") 
Else 
If Not ss.EndsWith("1") Then sb.Append("а") 
End If 
Else 
s0 = "месяцев" 
End If 
End If 

If RetValues.IndexOf("W") < 0 Then 
dd = dw 
Else 
Weeks = CInt(DateDiff(DateInterval.WeekOfYear, dw, d2)) 
dd = DateAdd(DateInterval.WeekOfYear, Weeks, dw) 
If dd > d2 Then 
Weeks -= 1 
dd = DateAdd(DateInterval.WeekOfYear, Weeks, dw) 
End If 
If Weeks > 0 Then 
ss = Right((100 + Weeks).ToString, 2) 
If sb.Length > 0 Then sb.Append(sr) 
sb.Append(Weeks.ToString & " недел") 
If ss.EndsWith("0") Or ss.StartsWith("1") Or CInt(Right(ss, 1)) >= 5 Then 
sb.Append("ь") 
Else 
sb.Append(IIf(ss.EndsWith("1"), "я", "и")) 
End If 
Else 
s0 = "недель" 
End If 
End If 

If RetValues.IndexOf("D") < 0 Then 
dh = dd 
Else 
Days = CInt(DateDiff(DateInterval.Day, dd, d2)) 
dh = DateAdd(DateInterval.Day, Days, dd) 
If dh > d2 Then 
Days -= 1 
dh = DateAdd(DateInterval.Day, Days, dd) 
End If 
If Days > 0 Then 
ss = Right((100 + Days).ToString, 2) 
If sb.Length > 0 Then sb.Append(sr) 
sb.Append(Days.ToString & " д") 
If ss.EndsWith("0") Or ss.StartsWith("1") Or CInt(Right(ss, 1)) >= 5 Then 
sb.Append("ней") 
Else 
sb.Append(IIf(ss.EndsWith("1"), "ень", "ня")) 
End If 
Else 
s0 = "дней" 
End If 
End If 

If RetValues.IndexOf("H") < 0 Then 
dn = dh 
Else 
Hours = CInt(DateDiff(DateInterval.Hour, dh, d2)) 
dn = DateAdd(DateInterval.Hour, Hours, dh) 
If dn > d2 Then 
Hours -= 1 
dn = DateAdd(DateInterval.Hour, Hours, dh) 
End If 
If Hours > 0 Then 
ss = Right((100 + Hours).ToString, 2) 
If sb.Length > 0 Then sb.Append(sr) 
sb.Append(Hours.ToString & " час") 
If ss.EndsWith("0") Or ss.StartsWith("1") Or CInt(Right(ss, 1)) >= 5 Then 
sb.Append("ов") 
Else 
If Not ss.EndsWith("1") Then sb.Append("а") 
End If 
Else 
s0 = "часов" 
End If 
End If 

If RetValues.IndexOf("N") < 0 Then 
ds = dn 
Else 
Minutes = CInt(DateDiff(DateInterval.Minute, dn, d2)) 
ds = DateAdd(DateInterval.Minute, Minutes, dn) 
If ds > d2 Then 
Minutes -= 1 
ds = DateAdd(DateInterval.Minute, Minutes, dn) 
End If 
If Minutes > 0 Then 
ss = Right((100 + Minutes).ToString, 2) 
If sb.Length > 0 Then sb.Append(sr) 
sb.Append(Minutes.ToString & " минут") 
If Not (ss.EndsWith("0") Or ss.StartsWith("1") Or CInt(Right(ss, 1)) >= 5) Then 
sb.Append(IIf(ss.EndsWith("1"), "а", "ы")) 
End If 
Else 
s0 = "минут" 
End If 
End If 

If RetValues.IndexOf("N") >= 0 Then 
Seconds = CInt(DateDiff(DateInterval.Second, ds, d2)) 
If Seconds > 0 Then 
ss = Right((100 + Seconds).ToString, 2) 
If sb.Length > 0 Then sb.Append(sr) 
sb.Append(Seconds.ToString & " секунд") 
If Not (ss.EndsWith("0") Or ss.StartsWith("1") Or CInt(Right$(ss, 1)) >= 5) Then 
sb.Append(IIf(ss.EndsWith("1"), "а", "ы")) 
End If 
Else 
s0 = "секунд" 
End If 
End If 

If sb.Length > 0 Then 
Return New SqlString(sb.ToString) 
Else 
Return New SqlString("0 " & s0) 
End If 
End Function 
End Class 
[/syntax] 

Пример использования: 

[syntax="sql"]Select 
Лет = dbo.ufnGetAgo('19621010',GETDATE(), 'Y', 'Y'), 
Месяцев = dbo.ufnGetAgo('19621010',GETDATE(), 'M', 'YM'), 
ВсегоМесяцев = dbo.ufnGetAgo('19621010',GETDATE(), 'M', 'M'), 
[Возраст строкой] = dbo.ufnGetAgoString('19621010',GETDATE(), 'YMDHNS') 
UNION ALL 
Select 
Лет = dbo.ufnGetAgo('19621010',GETDATE(), 'Y', 'Y'), 
Месяцев = dbo.ufnGetAgo('19621010',GETDATE(), 'M', 'YM'), 
ВсегоМесяцев = dbo.ufnGetAgo('19921010',GETDATE(), 'M', 'M'), 
[Возраст строкой] = dbo.ufnGetAgoString('19921010',GETDATE(), 'YMDHNS') 
UNION ALL 
Select 
Лет = dbo.ufnGetAgo('19621010',GETDATE(), 'Y', 'Y'), 
Месяцев = dbo.ufnGetAgo('19621010',GETDATE(), 'M', 'YM'), 
ВсегоМесяцев = dbo.ufnGetAgo('19921010',GETDATE(), 'M', 'M'), 
[Возраст строкой] = dbo.ufnGetAgoString('19921015',GETDATE(), 'YMDHNS') 
UNION ALL 
Select 
Лет = dbo.ufnGetAgo('19621010',GETDATE(), 'Y', 'Y'), 
Месяцев = dbo.ufnGetAgo('19621010',GETDATE(), 'M', 'YM'), 
ВсегоМесяцев = dbo.ufnGetAgo('19921010',GETDATE(), 'M', 'M'), 
[Возраст строкой] = dbo.ufnGetAgoString('19921015',GETDATE(), 'wDHNS') 

-- И результат: 

Лет Месяцев ВсегоМесяцев Возраст строкой 
----------- ----------- ------------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
43 5 521 43 года, 5 месяцев, 28 дней, 12 часов, 7 минут, 34 секунды 
43 5 161 13 лет, 5 месяцев, 28 дней, 12 часов, 7 минут, 34 секунды 
43 5 161 13 лет, 5 месяцев, 23 дня, 12 часов, 7 минут, 34 секунды 
43 5 161 703 недели, 1 день, 12 часов, 7 минут, 34 секунды 
5 окт 09, 07:35    [7740650]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
Влом регистрироваться
Guest
Joris,

а почему не в форум "Работа"?
5 окт 09, 07:41    [7740654]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
Le Peace
Member

Откуда: Москва
Сообщений: 8969
Joris, покажите запросы, которые отсылаются на sql server и не отрабатывают в 2000-м.
5 окт 09, 09:26    [7740899]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
aleks2
Guest
Чем в такой хрени разбираться - легше свое написать. Короче выйдет...
alter function CalcAge(
@Birthday datetime, -- дата рождения
@CalcForDate datetime -- дата на которую надо вычислить возраст
)
returns @t table(
yeas int --полных лет
, months int -- полных месяцев
, days int -- полных дней
)
as
begin
  declare @y int, @m int, @d int

  set @y=DATEDIFF(year, @Birthday, @CalcForDate)

  set @Birthday=DATEADD(year, @y, @Birthday)
  if @Birthday>@CalcForDate begin
    SET @y=@y-1
    set @Birthday=DATEADD(year, -1, @Birthday)
  end

  set @m=DATEDIFF(month, @Birthday, @CalcForDate)

  set @Birthday=DATEADD(month, @m, @Birthday)
  if @Birthday>@CalcForDate begin
    SET @m=@m-1
    set @Birthday=DATEADD(month, -1, @Birthday)
  end

  set @d=DATEDIFF(day, @Birthday, @CalcForDate)

  insert @t
  VALUES(@y, @m, @d)
  return
end
5 окт 09, 09:52    [7740999]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
vino
Member

Откуда:
Сообщений: 1191
Joris
Привет Всем!!!!
Ребята можете перевести этот код для SQL SERVER 2000, есть куче пример функция вычисление возраста в сайте, два три примера проверил все равно где то неправильно подсчитает., если можете помогите пожалуйста очень нужен……….
...
Лет Месяцев ВсегоМесяцев Возраст строкой
----------- ----------- ------------ ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
43 5 521 43 года, 5 месяцев, 28 дней, 12 часов, 7 минут, 34 секунды
43 5 161 13 лет, 5 месяцев, 28 дней, 12 часов, 7 минут, 34 секунды
43 5 161 13 лет, 5 месяцев, 23 дня, 12 часов, 7 минут, 34 секунды
43 5 161 703 недели, 1 день, 12 часов, 7 минут, 34 секунды

с чего вы взяли, что этот код корректен, если вы его не проверяли?
не проще ли воспользоваться поиском?
5 окт 09, 12:37    [7742128]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
vino
Member

Откуда:
Сообщений: 1191
вам действительно нужна на sql-сервере такая универсально-параметризованная функция?
FUNCTION ufnGetAgo(d1 As Date,
d2 As Date,  
RetValue As Char OUTPUT, 
RetValues As String = "YMDHNS" 
) as nvarchar(4000)
...
c точностью до секунды?
И производительность не волнует?
5 окт 09, 12:45    [7742190]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
Joris
Member

Откуда:
Сообщений: 186
vino, вот с этого сайта я скопироваль приме [url=] http://bbs.vbstreets.ru/viewtopic.php?t=19775[/url] там для VB есть функция вычисления возраста работает на 100% правильно и эту функцию переводили в MS SQL 2005 наверно тоже как функция VB работает…, поиском воспользовался много примеров проверил все равно где то неправильно подсчитает….
5 окт 09, 13:01    [7742309]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
vino
Member

Откуда:
Сообщений: 1191
vino
вам действительно нужна на sql-сервере такая универсально-параметризованная функция?
функция, считающая возраст с точностью до секунды сделать реально, но форматирование строк - это нетипичная для сервера операция, может, достаточно в клиенте воспользоваться уже имеющейся vb-функцией?
5 окт 09, 13:14    [7742372]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
Joris
Member

Откуда:
Сообщений: 186
vino
вам действительно нужна на sql-сервере такая универсально-параметризованная функция?

да обязательно на сервере...
vino
функция, считающая возраст с точностью до секунды сделать реально

вот это мне нужен...
vino
может, достаточно в клиенте воспользоваться уже имеющейся vb-функцией?

нет недостаточно, мне в сервере нужен...
5 окт 09, 13:24    [7742433]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
Glory
Member

Откуда:
Сообщений: 104760
Joris

vino
может, достаточно в клиенте воспользоваться уже имеющейся vb-функцией?

нет недостаточно, мне в сервере нужен...

И в чем конкретная проблема то у вас ?
5 окт 09, 13:28    [7742475]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
Joris
Member

Откуда:
Сообщений: 186
Glory
И в чем конкретная проблема то у вас ?

нужен функция вычисление возраста в SQL 2000 есть готовый пример но для SQL 2005 надо перевести или может тоже готовая функция есть для 2000-го....
5 окт 09, 13:36    [7742523]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
Glory
Member

Откуда:
Сообщений: 104760
Joris
Glory
И в чем конкретная проблема то у вас ?

нужен функция вычисление возраста в SQL 2000 есть готовый пример но для SQL 2005 надо перевести или может тоже готовая функция есть для 2000-го....

То, что вы привели в начале темы НЕ является готовой функцией на TSQL
Это исходники создания внешней библиотеки на Visual Basic, которая потом будет присоединена к MSSQL
5 окт 09, 13:40    [7742563]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
Joris
Member

Откуда:
Сообщений: 186
Glory,

Хорошо, все таки как надо решать проблему, есть таблица примерно 100 записей:
Таблица: tb_Date, Столбцы: ФИО и Дата рождения, как вычислить возраст ?
5 окт 09, 14:50    [7743081]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
Glory
Member

Откуда:
Сообщений: 104760
Joris
Glory,

Хорошо, все таки как надо решать проблему, есть таблица примерно 100 записей:
Таблица: tb_Date, Столбцы: ФИО и Дата рождения, как вычислить возраст ?

Найти алгоритм и написать по нему функцию
5 окт 09, 15:01    [7743176]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
PaulYoung
Member

Откуда: Москва
Сообщений: 2549
Joris, вот Вам самый простой пример
DECLARE @tb_Date TABLE ([ФИО] varchar(256), [Дата рождения] datetime)

INSERT @tb_Date SELECT 'иванов иван иваныч', '19770501'
INSERT @tb_Date SELECT 'петров петр петрович', '19670401'
INSERT @tb_Date SELECT 'сидоров сидор сидорыч', '19580211'

SELECT [ФИО], DATEDIFF(yy, [Дата рождения], GETDATE()) AS [Возраст] FROM @tb_Date
5 окт 09, 15:07    [7743215]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
Joris
Member

Откуда:
Сообщений: 186
PaulYoung,
нет, в таком формате надо, например: 6 Лет, 5 Месяцев, 25 Дней
5 окт 09, 15:16    [7743281]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
Glory
Member

Откуда:
Сообщений: 104760
Joris
PaulYoung,
нет, в таком формате надо, например: 6 Лет, 5 Месяцев, 25 Дней

Функция DATEDIFF может вам вернуть разницу также и в днях и в неделях и в минутах...
5 окт 09, 15:18    [7743294]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
PaulYoung
Member

Откуда: Москва
Сообщений: 2549
Joris,

смотреть тут
5 окт 09, 15:23    [7743325]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
vino
Member

Откуда:
Сообщений: 1191
Joris
... например: 6 Лет, 5 Месяцев, 25 Дней
для ленивых можно точнее дать разность между двумя датами в формате год месяц день
5 окт 09, 16:25    [7743788]     Ответить | Цитировать Сообщить модератору
 Re: Перевести код с 2005 на 2000 - го  [new]
vino
Member

Откуда:
Сообщений: 1191
хотя, припоминаю, что алгоритмы расчета очень разные и зависят от первичных инструкций, так что +1
Glory
Найти алгоритм и написать по нему функцию
если опишите алгоритм, то будет вам функция для 2000го
5 окт 09, 16:45    [7743953]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить