Использование глобальной переменной для SQL select statment - VB.NET

131
17

Я использую следующий код для заполнения DataGridView в форме DaisyServicesForm

'//Fill Table
GlobalVar.dataadapter2.Fill(GlobalVar.ds2, "Missing")
DaisyServicesForm.DataGridView3.AutoGenerateColumns = False
DaisyServicesForm.DataGridView3.DataSource = GlobalVar.ds2.Tables("Missing")

Поскольку он загружает данные в другую форму, я настроил свои переменные, используя открытый класс, чтобы они были доступны.

Public Class GlobalVar

Public Shared Filename2 As String

'//build table on left for missing items
Public Shared ds2 As DataSet = New DataSet()
Public Shared connStr2 As String = "server=inlt01\SQLEXPRESS; database=DaisyServices; integrated security=yes"
Public Shared sql2 As String = "SELECT i.[ID],i.[Site],i.[CLI],i.[CustomerName],i.[FromDate],i.[ToDate],i.[Quantity],i.[UnitCost],i.[TotalCost],i.[Description],i.[filenameonly],i.billingmonth as [CurrentBillingMonth], i.bill From [DaisyServices].[dbo].[DaisyServicesIndigo] i LEFT JOIN [DaisyServices].[dbo].[" & GlobalVar.Filename2 & "] s on i.[SITE]=s.[SITE] AND i.[CLI]=s.[CLI] AND i.[Quantity]=s.[Quantity] AND i.[UnitCost]=s.[UnitCost] AND i.[TotalCost]=s.[TotalCost] AND i.[Description]=s.[Description] WHERE s.[CLI] is NULL"
Public Shared conn2 As SqlConnection = New SqlConnection(GlobalVar.connStr2)
Public Shared comm2 As SqlCommand = New SqlCommand(GlobalVar.sql2, GlobalVar.conn2)
Public Shared dataadapter2 As SqlDataAdapter = New SqlDataAdapter(GlobalVar.comm2)

End Class

Проблема в том, что когда я запускаю код, с помощью события кнопки клика он выходит из строя со следующим сообщением об ошибке.

"Имя объекта или столбца отсутствует или пусто. Для операторов SELECT INTO убедитесь, что каждый столбец имеет имя. Для других операторов смотрите пустые псевдонимы. Псевдонимы, определенные как" или ", не разрешены. Измените псевдоним на действительное имя. "

Похоже, что переменная Filename не передается правильно.

Я протестировал переменную, существующую через MsgBox, и когда я жестко кодирую имя динамической таблицы, она работает нормально.

Любая помощь очень ценится.

спросил(а) 2021-01-28T00:40:56+03:00 2 месяца, 2 недели назад
1
Решение
61

Shared переменные создаются сразу же после запуска программы. У тебя есть

Public Shared comm2 As SqlCommand = New SqlCommand(GlobalVar.sql2, GlobalVar.conn2)

который создает команду с sql2, когда FileName2 еще не инициализирован.

Вы можете решить эту проблему, создав метод в вашем открытом классе для инициализации ваших соединений, команд и DataAdapters...

Public Class GlobalVar

Public Shared Filename2 As String

''build table on left for missing items
Public Shared ds2 As DataSet
Public Shared connStr2 As String
Public Shared sql2 As String
Public Shared conn2 As SqlConnection
Public Shared comm2 As SqlCommand
Public Shared dataadapter2 As SqlDataAdapter

Public Shared Sub InitializeConnection()
''Call this after you fill Filename2
ds2 = New DataSet()
connStr2 = "server=inlt01\SQLEXPRESS; database=DaisyServices; integrated security=yes"
sql2 = "SELECT i.[ID],i.[Site],i.[CLI],i.[CustomerName],i.[FromDate],i.[ToDate],i.[Quantity],i.[UnitCost],i.[TotalCost],i.[Description],i.[filenameonly],i.billingmonth as [CurrentBillingMonth], i.bill From [DaisyServices].[dbo].[DaisyServicesIndigo] i LEFT JOIN [DaisyServices].[dbo].[" & GlobalVar.Filename2 & "] s on i.[SITE]=s.[SITE] AND i.[CLI]=s.[CLI] AND i.[Quantity]=s.[Quantity] AND i.[UnitCost]=s.[UnitCost] AND i.[TotalCost]=s.[TotalCost] AND i. [Description]=s.[Description] WHERE s.[CLI] is NULL"
conn2 = New SqlConnection(GlobalVar.connStr2)
comm2 = New SqlCommand(GlobalVar.sql2, GlobalVar.conn2)
dataadapter2 = New SqlDataAdapter(GlobalVar.comm2)
End Sub
End Class

... НО Я действительно призываю вас переосмыслить ваш дизайн. Например, вы можете создать функцию в своем открытом классе, которая создаст все необходимые вам соединения и адаптеры для этой функции, откройте и закройте эти соединения и верните требуемый DataAdapter. Что-то вроде:

Public Class GlobalVar
''Do not declare anything here...

Public Shared Function FillData(ByVal Filename2 as string) as DataSet
''...instead put inside this function your connections, data adapters, sql sentences,
''and use them to fill and return the dataset with the data you need
End Function
End Class

ответил(а) 2021-01-28T00:40:56+03:00 2 месяца, 2 недели назад
44

Ваша переменная sql2 будет инициализирована при первом GlobalVar классу GlobalVar, используя текущее значение Filename2, которое будет Nothing. Будущие изменения в Filename2 не повлияют на стоимость sql2.

В качестве простого примера см. Следующий код (вставьте в LINQPad для тестирования):

Sub Main
Console.WriteLine("String1:{0}", Test.String1)
Console.WriteLine("String2:{0}", Test.String2)
Test.String1 = "Goodbye"
Console.WriteLine("String1:{0}", Test.String1)
Console.WriteLine("String2:{0}", Test.String2)
End Sub

' Define other methods and classes here
Public Class Test
Public Shared String1 As String = "Hello"
Public Shared String2 As String = Test.String1 & " World"
End Class

Это обеспечивает следующее:

String1:Hello
String2:Hello World
String1:Goodbye
String2:Hello World

ответил(а) 2021-01-28T00:40:56+03:00 2 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема