I am creating tables in the GUI of postgreSQL, PgAdmin3. There is an element that seems to be specious in the naming of the tables. The following is my fragmented comprehension of postgreSQL (I could be wrong if I am, please rectify). I am inserting tables in the database using the ETL tool Talend.
When there is only one schema in the database: No reference to the schema is mandatory
select * from tablename
When there is more than one schema in the database: Reference to the schema is mandatory and the reference to the schema is required in quotes
select * from "schema".tablename
There is something new I drifted upon yesterday and I do not know what might be causing pgAdmin to do this:
select * from "schema"."tablename"
I am not oblivious of the part that referencing to the specific schema is mandatory when there is more than one schema present in the same database and in quotes but why does one need to have the table name in quotes as well.
Related
I am learning SQL now, I would like to know what is meant within the from, what is contained before and after the dot.
For example:
SELECT *
FROM apler.W_WORKED_INVOICES wwi
What does apler stand for?
The W_WORKED_INVOICES is the table, correct?
appler is database schema. Schema is defined in the Oracle documentation as a collection of logical data structures or schema objects.
W_WORKED_INVOICES is a table created in the appler schema
I'm using DBeaver to write script for my PostgreSQL database.
I have a PostgreSQL DB with Tables autogenerated by C#/EFCore (Microsoft ORM) - I receive SQL Error [42P01] if I don't add double quotes around table names when I cut and paste my ORM queries to DBeaver. I got [42703] for fields without double quotes. I do not have to add double quotes in C# code but it appears to be required in DBeaver?
example:
select * from Dnp3PropertyBase => SQL Error [42P01]
select * from "Dnp3PropertyBase" => OK, all results shown...
Does anybody know if I can change a parameter in DBeaver somewhere in order to enter table names and fields without double quotes?
Note: Using DBeaver 22.3.2 (latest on 2023-01-11)
Update After reading: Postgresql tables exists, but getting "relation does not exist" when querying
show search_path => public, public, "$user"
SELECT * FROM information_schema.tables => All tables are in public schema
SELECT * FROM information_schema.columns => All columns are in public schema
Question: How to be able to cut and paste my EFCore generated queries from Visual Studio output window to DBeaver query without having any errors regarding table names and field names?
First let me copy #a_horse_with_no_name comment:
Unquoted names are folded to lower case in Postgres (and to uppercase
in Oracle, DB2, Firebird, and many others). So SomeTable is in fact
stored as sometable (or SOMETABLE). However quoted identifiers have to
preserve the case and are case sensitive then. So "SomeTable" is
stored as SomeTable
Many peoples recommended me to go with snake case which I didn't want to go with initialy because all tables were auto generated by EF Core (Microsoft C# ORM). I told myself that Microsoft would do standard things. Microsoft use the exact "class" name in code as the table name , by default. That appears to me very logical in order to stay coherent and apply the same rules everywhere. C# recommended to use Camel case for classes so each table names end by default in Camel case instead of snake case.
PostgreSQL seems to promote users to use snake casing because they lower case every non double quoted names. According to a_horse_with_no_name, and I think the same, only PostgreSQL has the behavior of lower casing down every table names and field names which are not double quoted in SQL script. That behavior (changing casing for non double quoted names) appears to me as being very limitative. It also has hidden effect that could be hard to find for non initiated peoples coming from other DB world.
According to PostgreSQL doc, they recommend to use nuget package (.UseSnakeCaseNamingConvention()). It probably works fine for TPH (table per hierarchy) which is recommended by Microsoft for performance. But it does not works for table name for TPC (table per class) because of actual bugs in EFCore 7 (see Github project).
I received that message at the end of "update-database":
Both 'WindTurbine' and 'ResourceGenerator' are mapped to the table
'resource_generator'. All the entity types in a non-TPH hierarchy (one
that doesn't have a discriminator) must be mapped to different tables.
See https://go.microsoft.com/fwlink/?linkid=2130430 for more
information.
PostgreSQL doc : TPH supported OK but not for table in TPC (2023-01-12). I use TPC then I had to force each table name directly through TableAttribute.
My solution For table name, I use snake casing by manually add a "Table" attribute to each of my classes with the proper name like this sample:
[Table("water_turbine")]
public class WaterTurbine : ResourceGenerator
For fields, I use the EFCore.NamingConventions NugetPackage which works fine for fields names. Don't forget that if you have 2 classes mapped to the same object, it is because you are using TPC and did not force table name through TableAttribute.
This way all my table and fields names are snake casing and I can cut and paste any query dumped in my debugger directly in any SQL script window of DBeaver (or any SQL tool).
I've done DSN Less 2 different ways, but neither seem to have a way to specify a schema.
I tried specifying to schema like [schema]. but it doesn't work.
Any idea how to get it to link up?
You don't specify the schema in the connection string, but specify that schema in the table name (or view).
So, the default schema is "dbo".
So for table customers and schema "dbo", you use
dbo.Customers.
If the schema is sales, or other? then you go:
sales.Customers.
So the connection to the database is un-changed.
You don't have to (or can) specify the schema in the conneciton - you specifty it in the table name.
Of course the local table name can be ANY table name you want - and you are free to include or not the prefix like this
dbo_Customers
Sales_Contacts
But, you can could use
Customers
Contacts
In fact, in most cases, if you doing a migration from a standard Access data file back end to SQL server?
Then you of course will keep the client side (linked) table name as to what it was before, and the linked table name does not have any special meaning in regards to the schema used.
So only the table prefix (dbo.) is how you select/change/use a database schema, and this ONLY applies to the server side name you use when creating a table link. As noted the client side linked table can be any name you want, and it can "only" include the schema if YOU decide to adopt some naming convention.
So, you specify the schema by prefixing the server side table name when re-linking, or creating a table link.
thanks for your time. i edited my script, ran it, and still got this name: srp.dbo.gstDataCutover. i used to be able to do this easily with MSSQL2005. we've recently upgraded to 2008. and i dont remember doing it any other way...
Hi,
I'm trying to copy a table structure (columns, datatypes, schema) into a new table to have the same schema and structure, using the sql code below.
SELECT dbo.gstData.*
INTO [dbo.gstDataCutover]
FROM dbo.gstData
WHERE dbo.gstData.gstID < 1
My problem is, when i run this script the new table dbo.gstDataCutover is named as "dbo.gstDataCutover" but the schema is defaulted to the system schema ("srp"), which is actually srp.[dbo.gstDataCutover].
I want to copy both the structure and the schema.
Thanks!
Without any periods, the hard brackets indicate table name -- it's including the "dbo." in your example as part of the table name.
If you want the table created in the dbo schema:
SELECT t.*
INTO dbo.gstDataCutover
FROM dbo.gstData t
WHERE t.gstID < 1
Likewise, if you want the table created in the srp schema:
SELECT t.*
INTO srp.gstDataCutover
FROM dbo.gstData t
WHERE t.gstID < 1
The table name doesn't have any unusual characters, so there's no need to use hard brackets...
You can download the community edition of Visual Studio, which has features for comparing schemas as well as data. It will list the differences and allows you to select a set of changes, for which it will generate an update-script.
Earlier I had asked the question:
Where (or how) should I define the schema in a select statement when using PostgreSQL?
The answer I accepted was to modify the search_path for the connecting user so that the schema need not be specified in the SQL. However, now I wonder if I should always specify the schema in SQL rather than allow the schema to be automatically inferred by the search path. This seems like it would be a safer approach and would be more portable to other databases.
This question is different than the previous one in that I want to know what the best practices are for defining the schema in SQL, rather than how it can be done.
Should the schema always be explicitly defined in the SQL statement?
** Note: I would not hard code the schema name but would allow it to be configurable through the Web.config file so that the schema could change from one installation to another. **
It's a bad practice to hardcode schema into SQL statements.
You should keep it in the application settings and issue SET search_path after connecting to the database.
If your application is used by multiple users with their own schemas, your life will be much easier if you don't hardcode schema name into SQL.
In other words,
string query = "SELECT * FROM " + ConfigurationManager.AppSettings.Get("schema") + ".table";
is a bad way;
SQLCommand("SET search_path = " + ConfigurationManager.AppSettings.Get("schema"), connection).ExecuteNonQuery();
string query = "SELECT * FROM table";
is a good way.
Let's see - in the DB of the app I maintain there are around a dozen schemas. What would be the order if I put them in "search_path"? And would I put in the schema names (not the tables name and not the fully-qualified table names) in the configuration?
As you have guessed by now I do not use "search_path". But maybe you could store the fully-qualified table names in the configuration in case you ever change you mind about the names of the schemas or the tables themselves.