Access Caption property alternative for SQL Server - sql-server

I have searched for an answer to this question everywhere. There is one forum asking the same question but the solution given does not work. Alias and Caption is not the same thing. In MS Access you can set alias with SQL using:
([Field1]+[Field2]) as expr1
However, in query design view you can change the caption property of expr1 to something like salary. This will change the field name in datasheet view but does not change the alias, which means fields in reports or forms depending on this query does not have to be modified from expr1 to salary. The salary column will only appear in the datasheet view of the query.
I cannot find a way to do the same in SQL Server. Is there a way to achieve this?

You can add Caption property to linked table(linked view) in Access's TableDef
If there is no caption yet
Dim p As Property
Dim tbl As TableDef
Dim fld As Field
Dim Db As Database
Set Db = CurrentDb
Set tbl = Db.TableDefs("LINKED TABLE NAME")
Set fld = tbl.fields("FIELD NAME")
Set p = fld.CreateProperty("Caption", dbText, "CAPTION FOR FIELD")
fld.Properties.Append p
fld.Properties.Refresh
If there is caption and you want to change it
CurrentDb.TableDefs("LINKED TABLE NAME").fields("FIELD NAME").Properties("Caption").Value = "CAPTION FOR FIELD"
Or by GIU way: open linked table in design mode, go to field definition, print disired caption to Caption property, press save button

Related

Working with the data from LinQ SQL query

Using VS 2013 (VB) and SQL server 2016.
I have linQ query that returns two columns from a database. The query is as follows.
Dim val = (From value In db.ngc_flowTypes
Where value.defaultValue IsNot Nothing
Select value.flowName, value.defaultValue)
The data it returns is a as follows.
I want to iterate through each row of the results and pass the values to certain variables. A ForEach statement doesnt seem to work as it just runs through once. I am sure this must be easy but I ont quite understand it. Am I getting the data returned in the best way via my query? Can I transpose the data to a data table in VB? so I can work with it easier?
The end result I want is string for each flow name with its corresponding default value (along with some other text). So something like this.
dim strsubmission as string = flowName + " has a value of " + defaultValue
Use ToDictionary.
Dim val = (From value In db.ngc_flowTypes
Where value.defaultValue IsNot Nothing
Select value).ToDictionary(Function(key) key.flowName,
Function(value) value.defaultValue)
This will actually execute the SQL of the linq on the database (approx. Select * From ngc_flowTypes Where defaultValue Is Not NULL), traverse each record into a key/value pair (flowName, defaultValue) and put it into a in-memory dictionary variable (val).
After that you can do whatever you like with the dictionary.
For Each flowName In val.Keys
Console.WriteLine("{0} has a value of {1}", flowName, val(flowName))
Next
Edit:
This will only work as long flowName is unique in table ngc_flowTypes

Pulling data from an access tabel and inserting it in another tabel

Im having some trouble with the design of my database. In microsoft Access I have two tables. One named table1 this table contains three fields (Name, Surname and Birthdate). The other table, named table2 contains two fields (Name and Surname). I want the following to happen. If I make a new record in table1 using a form the Name and Surname get passed/inserted to table2 automaticly. What is the best way of doing this? I was messing around with the primary key but that doenst seem to work. And since I'm a beginner I dont know where to go from here.
Thanks in advance for your time and efford!
Just figured out the awnser to my question! I used the following code
Private Sub addNew_Click()
Dim db As Object
Dim rst As Recordset
Set db = CurrentDb
Set rst = db.OpenRecordset("select * from Person", dbOpenDynaset)
rst.AddNew
rst!PeopleSoftNr = tbPeopleSoftNr.Value
rst!Name = tbName.Value
rst!Birthday = tbBirthday.Value
rst.Update
Set rst2 = db.OpenRecordset("select * from Dental", dbOpenDynaset)
rst2.AddNew
rst2!PeopleSoftNr = tbPeopleSoftNr.Value
rst2!Dental = tbDental.Value
rst2.Update
End Sub
This allows me to write data to multiple tables.
In my opinion the best way to do, what you described, is creating a form for the personal data and include a subform to assign courses of the persons.
Detail information about the courses should be edited in an own form for the courses.

Access 2013 ComboBox based on Combobox with Junction Table

Good day. I would like to know why a Parameter Request pops up when executing a query. I have a form with 2 comboboxes where the 2nd one depends on the value in the 1st one. I do know how to do this when it involves 2 tables. I am having trouble when there is a many to many relationship.
Table 1: name - Supply_Sources, fields - Source_ID(pk), SupplySourceName
Table 2: name - Warehouse_Locations, fields - WLocation_ID(pk), Location_Name
Table 3 (junction): name - SupplySource_WarehouseLocation, fields - Supply_Source_ID(pk), Location_In_ID(pk)
On my form frmInventoryReceivedInput I have cboSupplySource and cboWLocation.
I populate cboSupplySource with
SELECT [Supply_Sources].[Source_ID], [Supply_Sources].[SupplySourceName] FROM Supply_Sources;
I am trying to get a drop down list in the cboWLocation based on the value in cboSupplySource. I am wanting to see the location names of where the supplies are placed in the warehouse.
I have a requery in cboSupplySource After Update (with cboWLocation as the control name). The SQL that I have come up with so far is:
SELECT Warehouse_Locations.Location_Name,
SupplySource_WarehouseLocation.Supply_Source_ID,
SupplySource_WarehouseLocation.Location_In_ID
FROM Warehouse_Locations RIGHT JOIN (Supply_Sources LEFT JOIN
SupplySource_WarehouseLocation ON Supply_Sources.Source_ID =
SupplySource_WarehouseLocation.Supply_Source_ID) ON
Warehouse_Locations.WLocation_ID =
SupplySource_WarehouseLocation.Location_In_ID
WHERE (((Warehouse_Locations.Location_Name)=[frmInventoryReceivedInput].[cboSupplySource]));
When it runs, on tabbing out of cboSupplySource, Enter Parameter Value dialogue box pops up, looking for frmInventoryReceivedInput.cboSupplySource input. Nothing I input brings up the correct list in cboWLocation.
Obviously, I do not have the correct select statement. Any help would be appreciated.
For cboWLocation try the recordSource query:
SELECT Warehouse_Locations.Location_Name
FROM Warehouse_Locations INNER JOIN (Supply_Sources INNER JOIN
SupplySource_WarehouseLocation ON Supply_Sources.Source_ID =
SupplySource_WarehouseLocation.Supply_Source_ID) ON
Warehouse_Locations.WLocation_ID =
SupplySource_WarehouseLocation.Location_In_ID
WHERE ((Supply_Sources.SupplySourceName)=([Forms]![frmInventoryReceivedInput].[cboSupplySource]))
Be aware, that the combobox columns have to be set to columncount 1 in this case with appropriate column width, because you said you only want to see the location names. Further, you should be sure that cboWLocation is not bound to a Control Source, to not overwrite anything.
You can apply it in VBA at the cboWLocation Enter Event.
In the following code example, the combobox cboWLocation is only updated, if there is a value in combobox cboSupplySource.
Private Sub cboWLocation_Enter()
If not (isNull(Me!cboSupplySource) Or Me!cboSupplySource.ListIndex = -1) then
Me.cboWLocation.RowSource = strSQL 'Put here the previous mentioned SQLString
End if
End Sub
HINT: It would be better for performance, when you change the bound column in cboSupplySource to the PK SourceID instead of the name. (With two columns in combobox cboSupplySource) Then use this PK to compare in your WHERE statement instead of the name. this is what keys in tables are for.
Edit: In the WHERE statement, maybe you have to put the namecomparison between ' ' because it is a string

Records are sorted in SQL Server, but when brought to MS Access subform, the sorting is different

My query in SQL Server is sorted by several factors, and when I execute it the ordering is all correct. I have some subforms that are populated using the following code:
Set db = OpenDatabase("", False, False, globalstrSQLConnection)
strSQL = "SELECT * FROM qryTaskSimple"
Set rs = db.OpenRecordset(strSQL, dbOpenSnapshot, dbSeeChanges)
Set Me.Recordset = rs
where globalstrSQLConnection is the connection to the database on my my SQL Server and qryTaskSimple is the query mentioned above. But the subforms are sorted by a completely different criterion. Instead of being sorted by:
ORDER BY CASE WHEN tblTask.JobNum LIKE '***FULL***' THEN 0 ELSE 1 END, DivisionSortID, SuperintendentSortID, ISNULL(dbo.tblTask.Ordering, 999999999),
dbo.tblTask.JobNum, dbo.tblTask.Sequence
as stated inside the query, it seems to be sorted by only tblTask.JobNum... even when I replace the entire ORDER BY clause with ORDER BY DivisionSortID... And I don't have any VBA code that further sorts the subforms.
Queries and tables in Access have an underlying query/table object order by that can over-ride the SQL order by. You can see it (and remove it) in respective object properties.
It can be pretty frustrating and I'm not really sure if that's what's going on, but regardless, you can force desired sorting by simply adding it to your SQL statement, treating the query as a table.
strSQL = "SELECT * FROM qryTaskSimple ORDER BY <your desired sorting using any qryTaskSimple cols>"
if that doesn't work, then try the (sub)forms orderby at the form's load() event:
Private Sub Form_Load()
me.orderby = "your order by statements"
if me.orderbyon = false then me.orderbyon = true
End Sub

Entity Framework - how to get database column datatype from metadata

Is there a way to get the database column DataType length information given a table's EntityType?
Example SQL (SQL Server) that you can run to see precisely what information I am looking for:
select
sys.tables.name as 'Table Name',
sys.columns.name as 'Column Name',
sys.systypes.name as 'DataType',
sys.columns.max_length as 'Max Length',
sys.columns.precision as 'Precision'
from
sys.columns, sys.systypes, sys.tables
where
sys.columns.system_type_id = sys.systypes.xtype
and sys.systypes.name <> 'sysname'
and sys.tables.type = 'U'
and sys.tables.name <> 'sysdiagrams'
and sys.columns.object_id=sys.tables.object_id
order by
sys.tables.name, sys.columns.column_id;
The last 3 columns contain the data that I would like to have access to because I'm generating some documentation. One example reason for the documentation is: Entity Framework will throw an Exception by default if a string is set on a property that can't support it's length. A developer without access to the database metadata has a challenge with the discoverability of length requirements in this case.
Thanks,
Aaron
Unfortunately no.
Even if that information is correctly captured in the SSDL (i.e. the Storage Schema Definition language) there is no public API in EF to go from C-Space (conceptual model) property to S-Space (storage model) column.
If your model is simple you can perhaps infer that information, using the EF metadata workspace and some simple heuristics, but once things get even a little complicated, those heuristics will break down.
Your only option at that point is to write code to interpret MSL (mapping or CS-Space) files, and use that in conjunction with the MetadataWorkspace to go from C-Space to S-Space.
EDIT: as pointed out by KristoferA you often have the attribute on the C-Space property, so you can go to directly to that. Unfortunately that is not always the case, and often it gets out of sync with the database.
I'm pretty sure that Julie Lerman's book covers how to get maxlength, at least a tool to validate against it, by making changes in the POCO creation. Chapter 13, starts around page 356. Example 13-12 covers it, it starts with
string MaxLengthValidation(EdmProperty prop)...
it's copyrighted material so I won't cut/paste it, but I hope you can buy a copy of her book and get the info.
Yes, this is possible: (EF6.1)
<Extension>
Public Function GetColumns(Of TEntity)(Db As IObjectContextAdapter) As List(Of DataColumn)
Dim oMetadata As MetadataWorkspace
Dim oObjects As ObjectItemCollection
Dim oContext As ObjectContext
Dim oColumn As DataColumn
Dim oQuery As Func(Of EdmProperty, Boolean)
Dim oType As EntityType
GetColumns = New List(Of DataColumn)
oContext = Db.ObjectContext
oMetadata = oContext.MetadataWorkspace
oObjects = oMetadata.GetItemCollection(DataSpace.OSpace)
oType = oMetadata.GetItems(Of EntityType)(DataSpace.OSpace).
Single(Function(EntityType As EntityType) oObjects.GetClrType(EntityType) Is GetType(TEntity))
oQuery = Function(EdmProperty As EdmProperty) EdmProperty.DeclaringType.Name = oType.Name
oType.Properties.ToList.ForEach(Sub(Column As EdmProperty)
oColumn = New DataColumn With
{
.AutoIncrement = Column.IsStoreGeneratedIdentity,
.AllowDBNull = Column.Nullable,
.ColumnName = Column.Name,
.DataType = Column.PrimitiveType.ClrEquivalentType,
.Caption = Column.Name
}
If oColumn.DataType Is GetType(String) Then
oColumn.MaxLength = Column.MaxLength.GetValueOrDefault
Else
oColumn.MaxLength = -1
End If
GetColumns.Add(oColumn)
End Sub)
End Function

Resources