零长度分隔标识符错误在PostgreSQL函数上

huangapple go评论95阅读模式
英文:

Zero length delimited identifier error on postgresql function

问题

I have a table, HVACLoads with JSON columns CoolingLoads and HeatingLoads in PostgreSQL DB. I am just changing the properties of JSON using PostgreSQL JSON functions to update the inner properties by calling the function with migration builder during the Ef Core migration with c#. For example, the data structure for cooling and heating loads is below.

  1. {
  2. "Roof": {
  3. "Total": 0,
  4. "Latent": 23,
  5. "SensibleTotal": 0,
  6. "PercentOfTotal": 0,
  7. "SensibleDelayed": 1,
  8. "SensibleInstant": 0,
  9. "SensibleReturnAir": 0
  10. },
  11. // ... (other properties)
  12. }

And below is the resulting structure

  1. {
  2. "Roof": {
  3. "Total": {
  4. "scalar": 0,
  5. "unit": "btuh"
  6. },
  7. "Latent": {
  8. "scalar": 23,
  9. "unit": "btuh"
  10. },
  11. "SensibleTotal": {
  12. "scalar": 0,
  13. "unit": "btuh"
  14. },
  15. "PercentOfTotal": 0,
  16. "SensibleDelayed": {
  17. "scalar": 1,
  18. "unit": "btuh"
  19. },
  20. "SensibleInstant": {
  21. "scalar": 0,
  22. "unit": "btuh"
  23. },
  24. "SensibleReturnAir": {
  25. "scalar": 0,
  26. "unit": "btuh"
  27. }
  28. },
  29. // ... (other properties)
  30. }

I am calling the below PostgreSQL function from migration and trying to update the properties.

  1. protected override void Up(MigrationBuilder migrationBuilder)
  2. {
  3. var options = new DbContextOptionsBuilder<APIDbContext>()
  4. .UseNpgsql(Startup.Configuration["ConnectionStrings:Postgres"])
  5. .Options;
  6. using var ctx = new APIDbContext(options);
  7. ctx.Database.OpenConnection();
  8. migrationBuilder.Sql(@"
  9. CREATE OR REPLACE FUNCTION set_loads(object_name text, field_name text)
  10. RETURNS void AS
  11. $$
  12. DECLARE
  13. query text;
  14. cooling_power_value numeric;
  15. heating_power_value numeric;
  16. BEGIN
  17. IF field_name = 'PercentOfTotal' THEN
  18. query := 'UPDATE ""HvacLoadReports"" SET ' || field_name || ' = ''' || PercentOfTotal::numeric || ''',
  19. ""CoolingLoads"" = jsonb_set(""CoolingLoads"", '''{' || object_name || '}'',''' || field_name || '''}''::jsonb, (""CoolingLoads""->>'{' || object_name || '}->>' || field_name || ''')::numeric, false),
  20. ""HeatingLoads"" = jsonb_set(""HeatingLoads"", '''{' || object_name || '}'',''' || field_name || '''}''::jsonb, (""HeatingLoads""->>'{' || object_name || '}->>' || field_name || ''')::numeric, false)';
  21. ELSE
  22. cooling_power_value := (""CoolingLoads""->>'{' || object_name || '}->>'scalar''')::numeric;
  23. heating_power_value := (""HeatingLoads""->>'{' || object_name || '}->>'scalar''')::numeric;
  24. query := 'UPDATE ""HvacLoadReports"" SET
  25. ""CoolingLoads"" = jsonb_set(""CoolingLoads"", '''{' || object_name || '}'',''' || field_name || '''}''::jsonb, (''{' || cooling_power_value || ',''btuh''}'')::jsonb, true),
  26. ""HeatingLoads"" = jsonb_set(""HeatingLoads"", '''{' || object_name || '}'',''' || field_name || '''}''::jsonb, (''{' || heating_power_value || ',''btuh''}'')::jsonb, true)';
  27. END IF;
  28. EXECUTE query;
  29. END
  30. $$ LANGUAGE plpgsql;
  31. ");
  32. Calling the above function using the below code inside the migration `Up` method:
  33. ```csharp
  34. migrationBuilder.Sql($"SELECT set_loads('{{Roof}}', '{{Total}}');");

But getting an error like

zero-length delimited identifier at or near """"""

Could anyone please point me to why I am getting the above error?

英文:

I have a table, HVACLoads with JSON columns CoolingLoads and HeatingLoadsin PostgreSQL DB. I am just changing the properties of JSON using PostgreSQL JSON functions to update the inner properties by calling the function with migration builder during the Ef Core migration with c#. For example, the data structure for cooling and heating loads is below.

  1. {
  2. &quot;Roof&quot;: {
  3. &quot;Total&quot;: 0,
  4. &quot;Latent&quot;: 23,
  5. &quot;SensibleTotal&quot;: 0,
  6. &quot;PercentOfTotal&quot;: 0,
  7. &quot;SensibleDelayed&quot;: 1,
  8. &quot;SensibleInstant&quot;: 0,
  9. &quot;SensibleReturnAir&quot;: 0
  10. },
  11. ...
  12. ....
  13. }

And below is the resulting structure

  1. {
  2. &quot;Roof&quot;: {
  3. &quot;Total&quot;: power { scalar: 0, unit: &quot;btuh&quot;},
  4. &quot;Latent&quot;: power { scalar: 23, unit: &quot;btuh&quot;},
  5. &quot;SensibleTotal&quot;: power { scalar: 0, unit: &quot;btuh&quot;},
  6. &quot;PercentOfTotal&quot;: 0,
  7. &quot;SensibleDelayed&quot;: power { scalar: 1, unit: &quot;btuh&quot;},
  8. &quot;SensibleInstant&quot;: power { scalar: 0, unit: &quot;btuh&quot;},
  9. &quot;SensibleReturnAir&quot;: power { scalar: 0, unit: &quot;btuh&quot;}
  10. },
  11. ...
  12. ....
  13. }

I am calling the below PostgreSQL function from migration and trying to update the properties.

  1. protected override void Up(MigrationBuilder migrationBuilder)
  2. {
  3. var options = new DbContextOptionsBuilder&lt;APIDbContext&gt;()
  4. .UseNpgsql(Startup.Configuration[&quot;ConnectionStrings:Postgres&quot;])
  5. .Options;
  6. using var ctx = new APIDbContext(options);
  7. ctx.Database.OpenConnection();
  8. migrationBuilder.Sql(@&quot;
  9. CREATE OR REPLACE FUNCTION set_loads(object_name text, field_name text)
  10. RETURNS void AS
  11. $$
  12. DECLARE
  13. query text;
  14. cooling_power_value numeric;
  15. heating_power_value numeric;
  16. BEGIN
  17. IF field_name = &#39;PercentOfTotal&#39; THEN
  18. query := &#39;UPDATE &quot;&quot;&quot;&quot;HvacLoadReports&quot;&quot;&quot;&quot;
  19. SET &#39; || field_name || &#39; = &#39;&#39;&#39; || PercentOfTotal::numeric || &#39;&#39;&#39;,
  20. &quot;&quot;&quot;&quot;CoolingLoads&quot;&quot;&quot;&quot; = jsonb_set(&quot;&quot;&quot;&quot;CoolingLoads&quot;&quot;&quot;&quot;, &#39;&#39;{&quot;&quot;&quot;&quot;&#39;&#39;&#39; || object_name || &#39;&#39;&#39;&quot;&quot;&quot;&quot;,&quot;&quot;&quot;&quot;&#39;&#39;&#39; || field_name || &#39;&#39;&#39;&quot;&quot;&quot;&quot;}&#39;&#39;, to_jsonb((&quot;&quot;&quot;&quot;CoolingLoads&quot;&quot;&quot;&quot;-&gt;&gt;&#39;&#39;&quot;&quot;&quot;&quot;&#39; || object_name || &#39;&quot;&quot;&quot;&quot;&#39;&#39;-&gt;&gt;&#39;&#39;&quot;&quot;&quot;&quot;&#39; || field_name || &#39;&quot;&quot;&quot;&quot;&#39;&#39;)::numeric), false),
  21. &quot;&quot;&quot;&quot;HeatingLoads&quot;&quot;&quot;&quot; = jsonb_set(&quot;&quot;&quot;&quot;HeatingLoads&quot;&quot;&quot;&quot;, &#39;&#39;{&quot;&quot;&quot;&quot;&#39;&#39;&#39; || object_name || &#39;&#39;&#39;&quot;&quot;&quot;&quot;,&quot;&quot;&quot;&quot;&#39;&#39;&#39; || field_name || &#39;&#39;&#39;&quot;&quot;&quot;&quot;}&#39;&#39;, to_jsonb((&quot;&quot;&quot;&quot;HeatingLoads&quot;&quot;&quot;&quot;-&gt;&gt;&#39;&#39;&quot;&quot;&quot;&quot;&#39; || object_name || &#39;&quot;&quot;&quot;&quot;&#39;&#39;-&gt;&gt;&#39;&#39;&quot;&quot;&quot;&quot;&#39; || field_name || &#39;&quot;&quot;&quot;&quot;&#39;&#39;)::numeric), false)&#39;;
  22. ELSE
  23. cooling_power_value := (&quot;&quot;&quot;&quot;CoolingLoads&quot;&quot;&quot;&quot;-&gt;&gt;&#39;&#39;&quot;&quot;&quot;&quot;&#39; || object_name || &#39;&quot;&quot;&quot;&quot;&#39;&#39;,&#39;&#39;&quot;&quot;scalar&quot;&quot;&#39;&#39;)::numeric;
  24. heating_power_value := (&quot;&quot;&quot;&quot;HeatingLoads&quot;&quot;&quot;&quot;-&gt;&gt;&#39;&#39;&quot;&quot;&quot;&quot;&#39; || object_name || &#39;&quot;&quot;&quot;&quot;&#39;&#39;,&#39;&#39;&quot;&quot;scalar&quot;&quot;&#39;&#39;)::numeric;
  25. query := &#39;UPDATE &quot;&quot;&quot;&quot;HvacLoadReports&quot;&quot;&quot;&quot;
  26. SET &quot;&quot;&quot;&quot;CoolingLoads&quot;&quot;&quot;&quot; = jsonb_set(&quot;&quot;&quot;&quot;CoolingLoads&quot;&quot;&quot;&quot;, &#39;&#39;{&quot;&quot;&quot;&quot;&#39;&#39;&#39; || object_name || &#39;&#39;&#39;&quot;&quot;&quot;&quot;,&quot;&quot;&quot;&quot;&#39;&#39;&#39; || field_name || &#39;&#39;&#39;&quot;&quot;&quot;&quot;}&#39;&#39;, to_jsonb((&quot;&quot;&quot;&quot;CoolingLoads&quot;&quot;&quot;&quot;-&gt;&gt;&#39;&#39;&quot;&quot;&quot;&quot;&#39; || object_name || &#39;&quot;&quot;&quot;&quot;&#39;&#39;-&gt;&gt;&#39;&#39;&quot;&quot;&quot;&quot;&#39; || field_name || &#39;&quot;&quot;&quot;&quot;&#39;&#39;)::numeric), false),
  27. &quot;&quot;&quot;&quot;HeatingLoads&quot;&quot;&quot;&quot; = jsonb_set(&quot;&quot;&quot;&quot;HeatingLoads&quot;&quot;&quot;&quot;, &#39;&#39;{&quot;&quot;&quot;&quot;&#39;&#39;&#39; || object_name || &#39;&#39;&#39;&quot;&quot;&quot;&quot;,&quot;&quot;&quot;&quot;&#39;&#39;&#39; || field_name || &#39;&#39;&#39;&quot;&quot;&quot;&quot;}&#39;&#39;, to_jsonb((&quot;&quot;&quot;&quot;HeatingLoads&quot;&quot;&quot;&quot;-&gt;&gt;&#39;&#39;&quot;&quot;&quot;&quot;&#39; || object_name || &#39;&quot;&quot;&quot;&quot;&#39;&#39;-&gt;&gt;&#39;&#39;&quot;&quot;&quot;&quot;&#39; || field_name || &#39;&quot;&quot;&quot;&quot;&#39;&#39;)::numeric), false),
  28. &quot;&quot;&quot;&quot;CoolingLoads&quot;&quot;&quot;&quot; = jsonb_set(&quot;&quot;&quot;&quot;CoolingLoads&quot;&quot;&quot;&quot;, &#39;&#39;{&quot;&quot;&quot;&quot;&#39;&#39;&#39; || object_name || &#39;&#39;&#39;&quot;&quot;&quot;&quot;,&quot;&quot;&quot;&quot;power&quot;&quot;&quot;&quot;}&#39;&#39;, &#39;&#39;{&quot;&quot;&quot;&quot;scalar&quot;&quot;&quot;&quot;: &#39;&#39; || cooling_power_value || &#39;&#39;, &quot;&quot;&quot;&quot;unit&quot;&quot;&quot;&quot;: &quot;&quot;&quot;&quot;btuh&quot;&quot;&quot;&quot;}&#39;&#39;, true),
  29. &quot;&quot;&quot;&quot;HeatingLoads&quot;&quot;&quot;&quot; = jsonb_set(&quot;&quot;&quot;&quot;HeatingLoads&quot;&quot;&quot;&quot;, &#39;&#39;{&quot;&quot;&quot;&quot;&#39;&#39;&#39; || object_name || &#39;&#39;&#39;&quot;&quot;&quot;&quot;,&quot;&quot;&quot;&quot;power&quot;&quot;&quot;&quot;}&#39;&#39;, &#39;&#39;{&quot;&quot;&quot;&quot;scalar&quot;&quot;&quot;&quot;: &#39;&#39; || heating_power_value || &#39;&#39;, &quot;&quot;&quot;&quot;unit&quot;&quot;&quot;&quot;: &quot;&quot;&quot;&quot;btuh&quot;&quot;&quot;&quot;}&#39;&#39;, true)&#39;;
  30. END IF;
  31. EXECUTE query;
  32. END
  33. $$ LANGUAGE plpgsql;
  34. &quot;);

Calling the above function using the below code inside the migration Up method:

  1. migrationBuilder.Sql($&quot;SELECT set_loads(&#39;{Roof}&#39;, &#39;{Total}&#39;);&quot;);

But getting an error like

> zero-length delimited identifier at or near """"

Could anyone please point me to why I am getting the above error?

答案1

得分: 0

Looks like you have escaped (doubled up) double-quotes one times too many.
Try this as SQL string in double-quotes:

  1. &quot;
  2. CREATE OR REPLACE FUNCTION set_loads(object_name text, field_name text)
  3. RETURNS void
  4. LANGUAGE plpgsql AS
  5. $func$
  6. DECLARE
  7. query text;
  8. cooling_power_value numeric;
  9. heating_power_value numeric;
  10. BEGIN
  11. IF field_name = &#39;PercentOfTotal&#39; THEN
  12. query := $q$
  13. UPDATE &quot;HvacLoadReports&quot;
  14. SET &quot;PercentOfTotal&quot; = jsonb_set(&quot;PercentOfTotal&quot;, &#39;Roof&#39;
  15. , (SELECT jsonb_object_agg(
  16. key
  17. , CASE WHEN key = &#39;PercentOfTotal&#39;
  18. THEN value
  19. ELSE jsonb_set(&#39;{&quot;power&quot;: {&quot;scalar&quot;: 0, &quot;unit&quot;: &quot;btuh&quot;}}&#39;, &#39;{power, scalar}&#39;, value)
  20. END)
  21. FROM jsonb_each(&quot;PercentOfTotal&quot; -&gt; &#39;Roof&#39;)))$q$;
  22. ELSE
  23. -- ... more
  24. END IF;
  25. -- RAISE NOTICE &#39;%&#39;, query; -- to debug
  26. EXECUTE query;
  27. END
  28. $func$;
  29. &quot;

I simplified so that all values nested in the key 'Roof' are replaced with the verbose form - except when the key is 'PercentOfTotal'.

Also note the use of dollar-quotes to preserve plain single-quotes. See:

Your life with Postgres is easier with legal, lower-case, unquoted identifiers. See:

英文:

Looks like you have escaped (doubled up) double-quotes one times too many.
Try this as SQL string in double-quotes:

  1. &quot;
  2. CREATE OR REPLACE FUNCTION set_loads(object_name text, field_name text)
  3. RETURNS void
  4. LANGUAGE plpgsql AS
  5. $func$
  6. DECLARE
  7. query text;
  8. cooling_power_value numeric;
  9. heating_power_value numeric;
  10. BEGIN
  11. IF field_name = &#39;PercentOfTotal&#39; THEN
  12. query := $q$
  13. UPDATE &quot;&quot;HvacLoadReports&quot;&quot;
  14. SET &quot;&quot;PercentOfTota&quot;&quot; = jsonb_set(&quot;&quot;PercentOfTota&quot;&quot;, &#39;Roof&#39;
  15. , (SELECT jsonb_object_agg(
  16. key
  17. , CASE WHEN key = &#39;PercentOfTotal&#39;
  18. THEN value
  19. ELSE jsonb_set(&#39;{&quot;&quot;power&quot;&quot;: {&quot;&quot;scalar&quot;&quot;: 0, &quot;&quot;unit&quot;&quot;: &quot;&quot;btuh&quot;&quot;}}&#39;, &#39;{power, scalar}&#39;, value)
  20. END)
  21. FROM jsonb_each(&quot;&quot;PercentOfTota&quot;&quot; -&gt; &#39;Roof&#39;)))$q$;
  22. ELSE
  23. -- ... more
  24. END IF;
  25. -- RAISE NOTICE &#39;%&#39;, query; -- to debug
  26. EXECUTE query;
  27. END
  28. $func$;
  29. &quot;

I simplified so that all values nested in the key 'Roof' are replaced with the verbose form - except when the key is 'PercentOfTotal'.

Also note the use of dollar-quotes to preserve plain single-quotes. See:

Your life with Postgres is easier with legal, lower-case, unquoted identifiers. See:

huangapple
  • 本文由 发表于 2023年4月17日 06:27:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76030629.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定