DBCheckComboBox get values in SQL Server - sql-server

I have a column that is NVarChar(MAX), it contains text like this: ;0,4,6
These are the Flag values from another table.
A. I set the EditValueFormat propertie of the component to cvfIndices
B. I put the table values from Table a to a TcxDBCheckComboBox component using code like this:
Query.Active := True;
while not Query.Eof do begin
cxDBCheckComboBox1.Properties.Items.AddCheckItem(QueryCaptionField.AsString);
Query.Next;
end;
Query.Active := False;
C. I assigned a datasource to point to that column I want to hold my value when I select the values in the program the text looks like this in the database: ;0,4,6 how should I query it to find what is selected from SQL Server?

Found the answer while using cvfIndices the value saved in the database represents the index of the value in the combobox so you can query it like this:
SELECT * FROM TechCardsData
LEFT JOIN TechCardsOperations
on
CHARINDEX(CAST(TechCardsOperations.ID-1 as nvarchar(max)),TechCardsData.OperationsFlags) <> 0
and everything works :) hope this helps someone :)

Related

How do I display Dynamics NAV table option field text values in SQL Server

Sometimes during Dynamics NAV development, it is helpful to take a quick look at the data using SQL Server. But because any fields of type option are an enumeration, all you get in SQL Server is the numeric value. I needed a quick and dirty way to get the option text values instead.
From within NAV you can read the OPTIONSTRING property of a FieldReference. This is a comma separated string. A job can be scheduled that will loop through all of the tables (Object virtual table filtered on table) by number, find the options strings and add them to a table. Then in a query you can find the option text value for the Table, Field No, and Field Value.
RecRef.OPEN(TableNo);
FOR i := 1 TO RecRef.FIELDCOUNT DO BEGIN
FieldRef := RecRef.FIELDINDEX(i);
IF FORMAT(FieldRef.TYPE) = 'Option' THEN BEGIN
optionstring := FieldRef.OPTIONSTRING;
c := NumberofOptions(optionstring);
FOR o := 1 TO c DO BEGIN
OptionsTable.INIT;
OptionsTable."Table No" := TableNo;
OptionsTable."Field No" := FieldRef.NUMBER;
OptionsTable."Option Value" := o-1;
OptionsTable."Option Text" := SELECTSTR(o, optionstring);
OptionsTable."Field Name" := FieldRef.NAME;
IF NOT OptionsTable.INSERT THEN OptionsTable.DELETE;
END;
END;
END;
To make this a little less painful, I created a macro enabled Excel file that parses the Dynamics NAV field option string into a Sql Server T-Sql Case statement. It provides a horizontal or vertical case statement and uses the field name as the column alias in Sql Server. Enjoy...
Here is a link to the Excel file
Excel File
I often get this problem. I created a table with option values (int) and names (string). The primary key is code, value. So you can use it also to resolve magicnumbers from other systems. Then you can easy join this table:
select Type, i.[Option] [Option Name]
from Object o
join [xxx$IntegerToOption] i on i.Code = 'OBJEKT TYP' and i.Integer = o.Type
order by o.Name
Output:
Type Option Name
5 Codeunit
2 Form
1 Table
2 Form
2 Form
1 Table
2 Form
5 Codeunit
3 Report

F# FSharp.Data.SqlClient not recognizing multiple return tables from Stored Procedure

I am not sure if this is possible but I have not been able to come across clear documentation for this use case. I am using F# 4 and the FSharp.Data.SqlClient library to connect to SQL Server 2016. I am wanting to call a stored procedure that returns multiple tables and turn those tables into the corresponding records. In this case the first table is made up of items and the second table is made up of customers.
My instinct is that it should look something like this:
let items, customers = cmd.Execute()
My gut is that items would be an IEnumerable<item> and customers would be an IEnumerable<customer> where item and customer are both Record types. What it appears is happening though is that FSharp.Data.SqlClient is only seeing the first returned table from the stored procedure. I am working on a SQL Server 2016 Developer instance. Here is the T-SQL to setup the example:
create table Item (
ItemID int identity(1, 1) primary key,
ItemName nvarchar(50)
)
go
create table Customer (
CustomerID int identity(1, 1) primary key,
CustomerName nvarchar(50)
)
go
insert into Item (ItemName) values ('A');
insert into Item (ItemName) values ('B');
insert into Item (ItemName) values ('C');
insert into Customer (CustomerName) values ('Gary');
insert into Customer (CustomerName) values ('Sergei');
insert into Customer (CustomerName) values ('Elise');
go
create procedure dbo.ExampleProcedure
as
begin
set nocount on;
select
ItemID,
ItemName
from Item
select
CustomerID,
CustomerName
from Customer
end;
And here is the F# script that I am testing with. It shows what I would like to be able to do but I get a compile error on the last line:
#r "../packages/FSharp.Data.SqlClient.1.8.2/lib/net40/FSharp.Data.SqlClient.dll"
#r "../packages/FSharp.Data.2.3.2/lib/net40/FSharp.Data.dll"
#r "System.Xml.Linq.dll"
open FSharp.Data
[<Literal>]
let connStr =
"Data Source=**connection string**;"
type queryExample = SqlProgrammabilityProvider<connStr>
do
use cmd = new queryExample.dbo.ExampleProcedure(connStr)
let items, customers = cmd.Execute()
I am wanting items to correspond to the first returned table and customers to correspond to the second returned table. The intellisense suggests that FSharp.Data.SqlClient is only seeing the first table. When I hover over cmd.Execute() the popup says "This expression was expected to have type 'a*'b but here has type System.Collections.Generic.IEnumerable<SqlProgrammabilityProvider<...>.dbo.ExampleProcedure.Record>". If I do the following I get access to the Items query in the stored procedure:
// Learn more about F# at http://fsharp.org. See the 'F# Tutorial' project
// for more guidance on F# programming.
#r "../packages/FSharp.Data.SqlClient.1.8.2/lib/net40/FSharp.Data.SqlClient.dll"
#r "../packages/FSharp.Data.2.3.2/lib/net40/FSharp.Data.dll"
#r "System.Xml.Linq.dll"
open FSharp.Data
[<Literal>]
let connStr =
"Data Source=**connection string**;"
type queryExample = SqlProgrammabilityProvider<connStr>
do
use cmd = new queryExample.dbo.ExampleProcedure(connStr)
for item in cmd.Execute() do
printfn "%A" item.ItemID
Is this even possible? Is my approach wrong? I could not find clear documentation on this use case but I thought it would be common enough it would be covered.
Update
Just to clarify what I am trying to achieve I am showing how I solve this in C#. In C# I create a DataSet object and populate it with the results of the Stored Procedure. From there I pick out the individual tables to work with. After extracting the tables I then use LINQ to transform the rows into the corresponding objects. It often looks something like the following:
using System.Data;
using System.Data.SqlClient;
var connStr = "**connection string**"
var sqlConnection = new SqlConnection(connStr );
var sqlCommand = new SqlCommand("ExampleProcedure", sqlConnection);
sqlCommand.CommandType = CommandType.StoredProcedure;
var dataSet = new DataSet();
var adapter = new SqlDataAdapter(sqlCommand);
adapter.Fill(dataSet);
var itemsTable = dataSet.Tables[0];
// Turn the itemsTable into a List<Item> using LINQ here
var customersTable = dataSet.Tables[1];
// Turn the customersTable into List<Customer> using LINQ here
I find this to be overly verbose for such a simple thing as extracting the individual tables but perhaps I am too sensitive to code clutter. I know that F# must have a more elegant and terse way to express this.
I don't know F#, however this is a data access problem.
When a stored procedure returns multiple resultsets, you need to access they in sequence, one by one.
cmd.ExecuteReader() returns an instance of a datareader pointing to the first resultset. You need to process this resultset, may be filling a list with instances of a custom class, than you call the method "NextResult" and you will have access to the next resultset and so on.
A reference for the method "NextResult": https://msdn.microsoft.com/pt-br/library/system.data.sqlclient.sqldatareader.nextresult(v=vs.110).aspx

SQL - How can I return a value from a different table base on a parameter?

SQL - How can I return a value from a different table base on a parameter
First time poster, long time reader:
I am using a custom Excel function that allows be to pass parameters and build a SQL string that returns a value. This is working fine. However, I would like to choose among various tables based on the parameters that are passed.
At the moment I have two working functions with SQL statements look like this:
_______FUNCTION ONE________
<SQLText>
SELECT PRODDTA.TABLE1.T1DESC as DESCRIPTION
FROM PRODDTA.TABLE1
WHERE PRODDTA.TABLE1.T1KEY = '&PARM02'</SQLText>
_______FUNCTION TWO________
<SQLText>
SELECT PRODDTA.TABLE2.T2DESC as DESCRIPTION
FROM PRODDTA.TABLE2
WHERE PRODDTA.TABLE2.T2KEY = '&PARM02'</SQLText>
So I am using IF logic in Excel to check the first parameter and decide which function to use.
It would be much better if I could do a single SQL statement that could pick the right table based on the 1st parameter. Logically something like this:
_______FUNCTIONS COMBINED________
IF '&PARM02' = “A” THEN
SELECT PRODDTA.TABLE1.T1DESC as DESCRIPTION
FROM PRODDTA.TABLE1
WHERE PRODDTA.TABLE1.T1KEY = '&PARM02'
ELSE IF '&PARM02' = “B” THEN
SELECT PRODDTA.TABLE2.T2DESC as DESCRIPTION
FROM PRODDTA.TABLE2
WHERE PRODDTA.TABLE2.T2KEY = '&PARM02'
ELSE
DESCRIPTION = “”
Based on another post Querying different table based on a parameter I tried this exact syntax with no success
<SQLText>
IF'&PARM02'= "A"
BEGIN
SELECT PRODDTA.F0101.ABALPH as DESCRIPTION
FROM PRODDTA.F0101
WHERE PRODDTA.F0101.ABAN8 = '&PARM02'
END ELSE
BEGIN
SELECT PRODDTA.F4801.WADL01 as DESCRIPTION
FROM PRODDTA.F4801
WHERE PRODDTA.F4801.WADOCO = '&PARM02'
END</SQLText>
You could try using a JOIN statement.
http://www.sqlfiddle.com/#!9/23461d/1
Here is a fiddle showing two tables.
The following code snip will give you the values from both tables, using the Key as the matching logic.
SELECT Table1.description, Table1.key, Table2.description
from Table1
Join Table2 on Table1.key = Table2.key
Here's one way to do it. If PARM03='Use Table1' then the top half of the union will return records and vice versa. This won't necessarily product good performance though. You should consider why you are storing data in this way. It looks like you are partitioning data across different tables which is a bad idea.
SELECT PRODDTA.TABLE1.T1DESC as DESCRIPTION
FROM PRODDTA.TABLE1
WHERE PRODDTA.TABLE1.T1KEY = '&PARM02'
AND &PARM03='Use Table1'
UNION ALL
SELECT PRODDTA.TABLE2.T2DESC as DESCRIPTION
FROM PRODDTA.TABLE2
WHERE PRODDTA.TABLE2.T2KEY = '&PARM02'</SQLText>
AND &PARM03='Use Table2'

oracle forms builder pl/sql - access a column that is dervied from other columns

I have a view in my database that has a bunch of fields derived from other information in the database, this is how the view is defined:
create view patient_account_view AS
select patient.p_mrn,
p_fname,
p_lname,
ammount_paid,
quantity*item_cost + repeats*item_cost "ammount_owing",
(quantity*item_cost + repeats*item_cost) - ammount_paid "balance"
from patient_account,
patient,
diagnosis,
prescribed_treatment,
items_used,
item,
perscription
where patient.p_mrn = diagnosis.p_mrn AND
patient_account.p_mrn = patient.p_mrn AND
diagnosis.prescribed_treatment_id = prescribed_treatment.prescribed_treatment_id AND
prescribed_treatment.prescribed_treatment_id = perscription.prescribed_treatment_id AND
items_used.ptreatment_id = prescribed_treatment.prescribed_treatment_id AND
items_used.item_number = item.item_number;
I would like to use pl/sql to access the information in the view to stick it into a form, but I'm getting a 'bad bind variable' error. How do I access this kind of attribute without having to recalculate the information stored there?
Here is the plsql that is problematic:
DECLARE
pmrn patient.p_mrn%TYPE;
var_ptuple patient%ROWTYPE;
var_accttuple patient_account%ROWTYPE;
BEGIN
pmrn := :PATIENT_BLOCK.MRN_FIELD;
SELECT * INTO var_ptuple from patient WHERE patient.p_mrn = pmrn;
SELECT * INTO var_accttuple from patient_account_view WHERE patient_account_view.p_mrn = pmrn;
:PATIENT_BLOCK.FNAME := var_ptuple.p_fname;
:PATIENT_BLOCK.LNAME := var_ptuple.p_lname;
:PATIENT_BLOCK.BALACNCE_OWING := var_accttuple.balance;
END;
The columns of your view patient_account_view do not match exactly the columns of the table patient_account, but in your code you have:
var_accttuple patient_account%ROWTYPE;
which means when you run this:
SELECT * INTO var_accttuple from patient_account_view ...
You haven't specified which columns get mapped to which record attributes, so Oracle requires that the column list matches exactly.
In this case, I'd expect you probably want to change the definition of the variable, e.g.
var_accttuple patient_account_view%ROWTYPE;
Side note
Since you're only using one attribute from the view, you can simplify your code as follows:
SELECT balance INTO :PATIENT_BLOCK.BALACNCE_OWING
from patient_account_view WHERE patient_account_view.p_mrn = pmrn;
and you no longer need var_accttuple.

Why doesn't my query return any results when I add a WHERE clause?

My Delphi application is connected to SQLite successfully.
procedure TForm1.Button1Click(Sender: TObject);
begin
ZQuery1.Close;
ZQuery1.SQL.Clear;
ZQuery1.SQL.Text := 'SELECT Name FROM city;';
ZQuery1.Open;
while not ZQuery1.EOF do
begin
Memo1.Lines.Add(ZQuery1.FieldValues['name']);
ZQuery1.Next;
end;
end;
The above code works fine and loads contents of field name from table city.
However,
procedure TForm1.Button1Click(Sender: TObject);
begin
ZQuery1.Close;
ZQuery1.SQL.Clear;
ZQuery1.SQL.Text := 'Select name from city WHERE district = :aField';
ZQuery1.Params.ParamByName('aField').Value := 'kabol';
ZQuery1.Open;
while not ZQuery1.EOF do
begin
Memo1.Lines.Add(ZQuery1.FieldValues['name']);
ZQuery1.Next;
end;
end;
Surprisingly, when I add a where clause, the query returns nothing! Could anyone suggest what is wrong in my code?
Here is an image of the data in my table:
You probably don't have any data that has a district of kabol. The addition of the WHERE clause would then result in no rows being returned, meaning that ZQuery1.Eof is immediately true, and your while not ZQuery1.Eof do loop never gets entered.
You can check this by changing your first query (the one that works) to something like this:
ZQuery1.SQL.Text := 'SELECT Name, District FROM City';
Then change the output to
Memo1.Lines.Add(ZQuery1.FieldValues['name'] + #9 +
ZQuery1.FieldValues['district']);
If you don't see at least one line in the memo that contains kabol in the rightmost column, you don't have any rows that match your WHERE criteria. (Note that most databases are case-sensitive, so kabol is not equal to Kabol; the first would match your WHERE, but the second would not.)
Your screenshot shows one database row where district is 'Kabol' (uppercase K), but your SQL query is looking for 'kabol' (lowercase k) instead. Assuming the query is comparing strins case-sensitively, that would explain why no row is found. So either fix the case in your query input, or else perform a case-insensitive query instead.

Resources