How to get SQL table property length attribute from SQL database tables - c#

I wonder if this is even possible, and I can't seem to find an answer. I am using Entity Framework / C# for a database application. I want to ensure that my front-end entities automatically match their counterparts in SQL for attributes like "StringLength". So, inside SQL, in my tables, if I specify, for example, "nvarchar(50)", I want to make sure that the user doesn't type more than 50 characters. I don't want to have to code this each time, so I'm looking for a way to have the C# application read the StringLength property from SQL and then apply logic in the front-end. I can't seem to find a way of getting this information by entity type/DbContext from the SQL database itself.
I thought I'd struck gold with this thread here: How to get the maximum length of a string from an EDMX model in code? but this seems to read from the entity schema defined in the C# application, not SQL.
I have attached a .png of the info I am trying to get from SQL for clarification. Any advice would be appreciated:

use this query to return Maximum length of column Description in table PaymentType
SELECT
CHARACTER_MAXIMUM_LENGTH
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_NAME = 'PaymentType' and COLUMN_NAME = 'Description'

Related

How To can Select**DB Table

If I have a database in each table where the ID field and its appropriate function in any field do not take the administrator behavior so that tables and field contents can be fetched until the serial number is unified without duplicate values
Appropriate in this context using except.
Is there a code that can fetch tables either in sql or in the Entity Framework ؟
Eexcept_Admin_except_List
List<int> tempIdList = answeripE.Select(q => q.ID).ToList();
var quslist = db.Qustion.Where(q => !tempIdList.Contains(q.ID));
\Thanks for the creator of "daryal" Get All Except from SQL database using Entity Framework
I need to do this without asking for each table and querying it. And also request SQL from the database as a whole without exception such as
select*
IDfield
FROM
MSDB_Table T
WHERE
T.id == MaxBy(T.OrderBy(x => x.id);
can replace "where TABLE1.id 'OR' Table2.id" decode all the tables and give a result.
All I'm looking forward to is that I can query one database on a whole, get it on a list without the use of tables or a composite key because it serves me in analyzing a set of data converted to other data formats, for example when representing a database in the form of JSON There are a lot of them on more than one platform and in a single database and to avoid the repetition of the data I need to do this or a comprehensive query may be compared or to investigate or like Solver Tool in Excel, so far did not get the answer to show me the first step is because it does not exist originally or because it is not possible?
If you want Entity Framework to retrieve all columns except a subset of them, the best way to do that is either via a stored procedure or a view. With a view you can query it using LINQ and add your predicates in code, but in a stored procedure you will have to write it and feed your predicate conditions into it...so it sounds like a view would be better for you.
Old example, but should guide you through the process:
https://www.mssqltips.com/sqlservertip/1990/how-to-use-sql-server-views-with-the-entity-framework/

Validate Sql Column Names

I have 4-5 tables in one database (not SQL Server).
In my UI, users can enter some SQL conditions together with column names in a textbox. I need to verify if the SQL is correct and if these columns exist, and show any errors accordingly. I am using C# for server side.
I have a SQL Server database where our UI stores all the UI related information.
One approach is to create all these tables (just the table structure) in my SQL Server as well and then query a simple select on each table and show the errors or success message(s) accordingly.
So basically I would have the where clause as below or more conditions:
where a = b and c in(1,2)
As mentioned above I would execute the above where clause against each table I created in SQL Server which would return error if column does not exist.
Is there a better way to approach this? I was thinking in case there is some other way to work without creating so many tables on my SQL Server.
I don't want to hard code these as the structure might change in near future. So looking for some maintainable solution. May be create a single table and store all this information in it.
Any suggestions are appreciated.
In SQL server you can query the system object :
information_schema.columns.
That contains a list of all columns for all tables and views.
However, I agree with previous comments - the design you describe is bad bad bad.
Ignoring the SQL injection troubles for a second, if the users have control over only the WHERE clause of the query, then you could try and run something like
select top 0 * from <tables> where <user-entered-where-clause>
and then gracefully handle any errors that are returned.
use dmv function in MS sql server to validate the query string.
assign user string to the variable #Str_query
declare #Str_query as nvarchar(max);
set #Str_query ='SELECT [role_code],[role_description] FROM [dbname].[dbo].[Roles]'
SELECT error_message FROM sys.dm_exec_describe_first_result_set(#Str_query, NULL, 0) WHERE column_ordinal = 0
if there is an error message then query string is not valid for execution.

How do I change the connection string to SQL Server in Excel Power query programmatically?

I'm attempting to create an Excel pivot table based on data in a Microsoft Dynamics NAV database.
The trick is I need the Excel to access the data directly from the SQL Server database with power query - and furthermore it must be able to access the data from the same table in multiple databases with different names and table names.
Does anybody have any experience or advice regarding this issue?
Step 1. First you should make a function where you can pass a server name, database name and table to be queried. Something like
let getData =(servername,dbname,tablename)=>
let
Source = Sql.Database(Servername, dbname, [Query="select abc , def from" & tablename & " where condition etc etc"]),
#"CustomStep1" = some action on Source,
in
.
.
#"CustomStepn" = some action on Added CustomStepn-1
in
#"Added CustomStepn"
in
getData
You have a function ready which you can use in a table to create a custom column.
Step 2. Now use a parameter table approach. Create a table in normal excel area.Something like
Server Name|DatabaseName | Table_to_be_used
Use now use menu option fromtable in powerquery options (or Data tab in Excel 16) Add a custom column in this table in powerquery steps using function getdata created in previous Step. Perform any other "Expand" (By default first function is going to return a table if you are not doing any other transformation) , "summarize" , Rename Operation.
However powerquery formula firewall is going to give you hardtime as powerquery doesn't trust Native SQL queries and you will have to approve each and every native sql query. You may try to uncheck checkbox for "Require user approval for new native database query" in query option.
Hope you get the idea and it helps.
Perhaps it would be worth looking into creating Query objects and exposing them via oData which is something Excel can read from. The benefit here is that it can handle table relations natively and can expose Flow Fields which you cannot see in direct SQL queries to the table.
Aside from a stored procedure to manage the different table names, there's not a simple way to query specific tables without hard coding the names in some capacity.
The Company table will give you the prefix$ and the table names are static between companies. You could write some fancy Excel logic to loop through them.

C# and SQLServer normalizing large sets of Urls

I have many tables in the database that have at least one column that contains a Url. And these are repeated a lot through-out the database. So I normalize them to a dedicated table and I just use numeric IDs everywhere I need them. I often need to join them so numeric ids are much better than full strings.
In MySql + C++, to insert a lot of Urls in one strike, I used to use multi-row INSERT IGNOREs or mysql_set_local_infile_handler(). Then batch SELECT with IN () to pull the IDs back from the database.
In C# + SQLServer I noticed there's a SqlBulkCopy class that's very useful and fast in mass-insertion. But I also need mass-selection to resolve the Url IDs after I insert them. Is there any such helper class that would work the same as SELECT WHERE IN (many, urls, here)?
Or do you have a better idea for turning Urls into numbers in a consistent manner in C#? I thought about crc32'ing the urls or crc64'ing them but I worry about collisions. I wouldn't care if collisions are few, but if not... it would be an issue.
PS: We're talking about tens of millions of Urls to get an idea of scale.
PS: For basic large insert, SQLBulkCopy is faster than SqlDbType.Structured. Plus it has the SqlRowsCopied event for a status tracking callback.
There is even a better way than SQLBulkCopy.
It's called Structured Parameters and it allows you to pass a table-valued parameter to stored procedure or query through ADO.NET.
There are code examples in the article, so I will only highlight what you need to do to get it up and working:
Create a user defined table type in the database. You can call it UrlTable
Setup a SP or query which does the SELECT by joining with a table variable or type UrlTable
In your backing code (C#), create a DataTable with the same structure as UrlTable, populate it with URLs and pass it to an SqlCommand through as a structured parameter. Note that column order correspondence is critical between the data table and the table type.
What ADO.NET does behind the scenes (if you profile the query you can see this) is that before the query it declares a variable of type UrlTable and populates it (INSERT statements) with what you pass in the structured parameter.
Other than that, query-wise, you can do pretty much everything with table-valued parameters in SQL (join, select, etc).
I think you could use the IGNORE_DUP_KEY option on your index. If you set IGNORE_DUP_KEY = ON on the index of the URL column, the duplicate values are simply ignored and the rest are inserted appropriately.

Is there any way to get the table hierarchy from a connection string in c#?

I have a current requirement to determine the table hierarchy from a sql statement within c#. For example, consider the following sql statement:
Select Table1.*, Table2.* from Table1
left join table2 on Table1.parentCol = Table2.childCol
That might return 7 columns, 3 for Table1 and 4 for table2. I need to know the column names, and ideally (though not mandatory) their types.
I have no control over what SQL Statement will be used, as this is a user entered field. In C# it's a very basic task to open a connection and create an SqlCommand using that statement. I have freedom to run the SQL into a SqlDataReader, or any other System.Data.SqlClient class if necessary, however I cannot find any combination that will return the columns, rather than the actual column values.
Is anyone able to help?
Many thanks and best regards
You cannot do what you are asking (easily).
More to the point, do not let users enter arbitrary TSQL (You will regret it at some point...).
Instead, create a 'Search' form that allows entering various params and use a parameterised query onto a view that joins all the tables/columns required.
There's no direct way. You'll need to parse names of all the tables from the sql query.
Once you have done that you'll need to write few queries on Information_Schema to get raw data for what you are looking for.
If you are on SQL Server, you may want to use Catalog View
ex-
Select * from sys.tables where [Name] = 'MyTable'

Categories